EF 4.3.1 - code first automatic migrations - how to specify column width - entity-framework-migrations

I am trying to find examples or documentation related to DbMigration and ColumnModel.
I simply want to specify width of string propery in DBMigration Up method
E.g.
AddColumn("Districts", "Code", c => c.String());
will create nvarchar(max) - and I want to specify maxlength(20) for example.
Is this integrated with EntityTypeConfiguration or I have to add also manually
this.Property(t => t.Name).HasColumnName("Code").IsRequired().HasMaxLength(20);
MSDN help doesn't give any examples and walkthrough on ef4 blog covers only basics

If you use AddColumn directly you can simply use:
AddColumn("Districts", "Code", c => c.String(maxLength: 20));
If you define max length in EntityTypeConfiguration (which is correct approach) EF Migration will handle it for you.

The configuration of the columns should be done as data annotations. To make a string column have a specific width, use the StringLengthAttribute:
[Required] // Makes column not null
[StringLength(20)] // Makes it a nvarchar(20) instead of nvarchar(max)
public string SomeString {get;set;}

Related

"Sequence contains more than one matching element" onload of any Kendo grid

I know this issue has arisen many times on Stack Overflow. I've looked at them, but believe this to be unique:
I'm not using .Single() or .SingleOrDefault() in any LINQ expressions
I checked my models for duplicates, like "Id" and "ID", there are none
This happens onload of any Kendo UI MVC grids, on any table, on any page in my website that has such a grid, and we have several different pages, each with their own grids
Just some history, we just changed some foreign keys to Guids from IDs (ints) in order to point them at different tables in the database than they are currently in the code. Models were updated, accordingly. We also added a view for the Kendo grid to be pointed at, and this was changed in the view. But even grids that have nothing to do with the original or new SQL view/C# models seem to have been affected. Now, during this phase:
public OurDatabase(bool enableLazyLoading=true)
: base("name=OurDBContext")
{
Database.SetInitializer<OurDatabase>(null);
((IObjectContextAdapter)this).ObjectContext.ContextOptions.ProxyCreationEnabled = enableLazyLoading;
((IObjectContextAdapter)this).ObjectContext.ContextOptions.LazyLoadingEnabled = enableLazyLoading;
}
It keeps giving the error "Sequence contains more than one matching element". It will highlight on that middle line with that error.
Can something changing in the database cause this? Code that once worked, and hasn't been changed since that time, now does not, and this is very confusing.
I found out the answers to my problem. Yes, plural.
First, if I commented out the public virtual DbSet<blah> blah { get; set; } in the database entity, and everything that had anything to do with its model, the old code would work again. So that told me the issues were in the model. I also thought I could name "blah" whatever I wanted. I found it should be named after the DB or view name, instead, so I updated that, accordingly.
Second, I found out I had some major issues with my models, which I had used some decorations on with little knowledge behind them. Ex.
[Key]
[Column(name:"GUID", order:2)]
public Guid Guid
It was #2 because ID was #1, and if I put ID in just like above, I got a green squiggly under ID saying 'MyProject.Entities' hides inherited member 'MyProject.Entities.PersistedEntity<int>.Id'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword.
That was because of the PersistedEntity<int> inherited class that had Id and Name in it, already, that a team member had added. I commented that out and declared the ID and Name columns (which also had the green squiggly until commenting out that class) the normal way.
Then I got an error on the composite keys, saying it could not order them (gee, I wonder why). So these are how they look, now:
[Key]
[Column(Order = 0)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int ID { get; set;}
[Key]
[Column(Order = 1)]
public Guid GUID { get; set;}
[Key]
[Column(Order = 2)]
[StringLength(60)]
public string Name { get; set;}
Which set the ordering and composite key correctly, starting at 0 instead of 1 that I had previously. I had other columns, too, so I continued with setting the [Key] and [Column(Order = x)] attributes on those, too.
Third, I also added a decoration above the class, calling it a table, even though this was for a view (weird):
[Table("My.View")]
Keeping things commented out that relates to adding new models in the controllers seems to be the way to go to troubleshoot this lousy, non-descript error that for me said nothing about the real, underlying issues - at least in this instance. I also didn't think ALL of my grids would stop working just because I added a model - even ones that were not pointed at the new model or the one it was replacing.
After I got the models with the right annotations, I was able to uncomment out the DbSets in my main database model, and because my team member used "Id", when I re-generated the model, I needed to update the ID the grid was using in the Kendo view:
.DataSource(dataSource => dataSource
.Ajax()
.Model
{
.model.Id(p => p.ID)
})
Also, note, I was only able to get it fully working after upgrading to Entity Framework 6.1. Before then, I was getting "Invalid object name 'dbo.My.View'". Apparently in previous versions of EF, you can't just add a model for a table/view and expect it to find it.

Change Code First database table to have PK not be identity column?

I have an MVC application using Code First data migrations and now, long after making a table, I'd like to change the PK column to not be an auto-generated Identity column. But I get the impression I just can't do this without having CodeFirst delete the table somehow (which will be hard given all the dependencies) and recreate it? Really wishing I didn't have to do that.
What I've tried:
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int AssessmentID { get; set; }
and this in OnModelCreating():
modelBuilder.Entity<Assessment>()
.Property(e => e.AssessmentID)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
When doing add-migration, it doesn't add anything. I tried manually adding this line but it does not update the db:
AlterColumn("dbo.Assessment", "AssessmentID", c => c.Int(nullable: false, identity:false));
I've concluded that this is indeed not possible. Like the post below says, there is no SQL Alter command to change the Identity status on a column, so CodeFirst can't create one. I plan to remove all migration files and rescaffold (things have gotten messy in other ways).
Remove Identity from a column in a table

EF Code First 4.1: how to map Member.UserId to the aspnet_Users.UserId?

I have a Member class:
public class Member
{
// key
public Guid UserId { get; set; }
// some other fields
}
Also I have a aspnet_Users table with has UserId primary column.
We can:
1). Add additional property MembershipUser to the Member object and get it's value by calling Membership.GetUser(this.UserId) method.
Also I've add
context.Database.ExecuteSqlCommand("ALTER TABLE [dbo].[Members] WITH CHECK ADD CONSTRAINT [FK_Members_aspnet_Users] FOREIGN KEY([UserId]) REFERENCES [dbo].[aspnet_Users] ([UserId])");
to the DataContext.Seed() method to ensure that Member can not be added without aspnet_Users account.
2). Use fluent API in OnModelCreating. If this a good case how to map them correctly?
What's the best choice? Any thoughts?
No matter how I tried to avoid it, I've found the best approach is to implement my own MembershipProvider and have it use my model, rather than trying to shoehorn my model into the built-in membership provider.
If you are going down the other route you have to map the ASP.NET Membership tables to your domain and derive your Member class from the ASP_User class (or vice versa if you want to ensure that all Users you create are Members). In the end, I've discovered that although it seems like more effort up front, implementing MembershipProvider is the easier approach.
You don't. Don't add foreign key constraints against the aspnet_* tables. It's a recipe for trouble. Membership is plug-in type system, and you have to treat it as a black box.
Simply lookup the data in your tables with the MembershipUser.ProviderUserKey as it's value. Something like this:
from m in Member where UserID == (Guid)Membership.GetUser().ProviderUserKey select t;

Entity Framework 4.1 - Code First with existing Database, how to define classes, using Attributes or EntityTypeConfiguration? What is the difference?

I have been studying the EF for a short time and cant find the answer to this question.
I have existing database and I am using CodeFirst to create classes for the model.
What is the difference in using Attributes and EntityTypeConfiguration to define parameters of table columns?
Since the database already has defined foreign keys and unique constraints, and so on, how and where to implement the validation for a best and most fluid result for use in ASP.NET MVC3?
Is it better to implement Attributes and CustomValidation or to use TryCatch blocks to catch errors from db?
Does Validator.TryValidateObject(myModelObject, context, results, true); use validation rules defined only as Attributes or can it use rules defined in EntityTypeConfiguration?
Thank You
Get the Entity Framework Power Tools CTP1 and it will reverse engineer your database and create entities, and a full data mapping. This is different than Model or Database first in that it generates a fluent model rather than using an .edmx file. You can see exactly how it works then.
See the following article about how you can create your entity classes from existing database :
http://blogs.msdn.com/b/adonet/archive/2011/03/15/ef-4-1-model-amp-database-first-walkthrough.aspx
Code generation templates will do the work for you, you don't need to write them if you have an existing db.
For validation, you can create new partial classes under the same namespace and put DataAnottations for your properties. Here is an example for you :
using System.ComponentModel.DataAnnotations;
using System.ComponentModel;
namespace TugberkUgurlu.App1.DataAccess.SqlServer {
[MetadataType(typeof(Country.MetaData))]
public partial class Country {
private class MetaData {
[Required]
[StringLength(50)]
[DisplayName("Name of Country")]
public string CountryName { get; set; }
[Required]
[StringLength(5)]
[DisplayName("ISO 3166 Code of Country")]
public string CountryISO3166Code { get; set; }
[DisplayName("Is Country Approved?")]
public string IsApproved { get; set; }
}
}
}
-Since the database already has defined foreign keys and unique constraints, and so on, how and where to implement the validation for a best and most fluid result for use in ASP.NET MVC3?
These should happen via your generated model. Keys are automatically inferred. If you reverse engineer an existing database the attributes will be created for you. If not, there are basic rules that are followed. The entity framework will attempt to use an auto incrementing primary key for example unless you tell it otherwise via
[DatabaseGenerated(System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.None)]
The relationships are already part of your model so there is your referential integrity, and the data annotations will define the validation rules.
-Is it better to implement Attributes and CustomValidation or to use TryCatch blocks to catch errors from db?
Implement attributes. Define your metadata classes with your attributes in them.
In addition you want to catch any db errors for anything else that is unexpected if your db has additional logic in there not defined in your model (try catch at some level should generally be used anyways for logging purposes_
-Does Validator.TryValidateObject(myModelObject, context, results, true); use validation rules defined only as Attributes or can it use rules defined in EntityTypeConfiguration?
As far as I'm aware only the attributes are used. I'm going to try to test this later though as I'd like a definite answer on this as well :)

Version grails domain class by DateTime

I'd like to version a grails domain class by DateTime such that:
each primary ID + DateTime property results in a new DB row (i.e. a new DB row per version)
the newest version can be found without having to specify the DateTime value
My knowledge of grails is a little limited right now and I don't understand how I can achieve this.
Consider the following domain class as an example:
import org.joda.time.DateTime
class Page {
String pageId
DateTime theVersion
String content
static constraints = {
pageId(nullable:false, blank:false, unique:true, matches:"[a-zA-Z\\._-]+")
content(nullable:false, blank:false)
}
static mapping = {
content(type:"text")
}
}
What changes are needed to ensure a new DB row is inserted per version? I'm assuming some form of constraint is required such that pageId+theVersion is unique but I don't know how to express this in the GORM DSL.
How might I get the most recent version without knowing the relevant DateTime value?
I'm envisaging something like:Page.findByPageIdAndTheVersionLessThanEquals('uniquePageId', new DateTime())
I expect this would find many objects not just one. I'd like to be able to also express the equivalent of ORDER BY theVersion DESC LIMIT 0,1
Just create the new versions with new Page(), not with get() - a new record will be inserted.
To assure uniqueness, put into constraints:
theVersion(unique: 'pageId')
Page.findByPageId(pageId, [sort: 'theVersion', order: 'desc', max: 1])
You can utilize Grails' dateCreated implicit timestamping feature - it will even work with joda-time plugin.
OTOH, why don't you utilize Grails' built-in version field? It provides you some features out of box and takes care for optimistic locking.

Resources