Reputation: 289
I'm moving to Entity Framework from an existing model and database. In that database, there are several tables with GUID columns which are not primary keys (or keys at all!). Each table has an ID column. The GUID columns have the ROWGUIDCOL property defined on them, as well as a DEFAULT(newid()).
Now, when I insert into the DB, I get all zeroes for this column.
I've tried using data annotations:
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Guid {get; set;}
The problem with this is that it drops the identity property on my ID column (and gives me insert errors). Beyond that, I noticed that for the following migration, EF actually generates identical SQL for both the up and down methods:
public override void Up()
{
AlterColumn("dbo.Client", "Guid", c => c.Guid(nullable: false, identity: true));
}
public override void Down()
{
AlterColumn("dbo.Client", "Guid", c => c.Guid(nullable: false));
}
With the generated sql of:
ALTER TABLE [dbo].[Client] ALTER COLUMN [Guid] [uniqueidentifier] NOT NULL
Why does the above migration create the same sql for both statements? How do I get EF to generate GUIDs? Can I/must I do this in client (code) space? If I must, how could I guarantee uniqueness across tables?
Upvotes: 5
Views: 3868
Reputation: 371
I had gotten some errors when trying to convert pre-existing ID ident columns into GUIDs. Computed wouldn't work, setting as identity wouldn't work. Setting to DatabaseGeneratedOption.None would cause errors stating i couldn't insert a null in the required field. I had a NewGuid generation in my constructor, but that didn't seem to help either.
To get it to work, i deleted my Migration .cs files and my database, then Using dataannotations, I was able to defeat the system by setting the new GUID ID to Key, DatabaseGeneratedOption.None and then putting a backing field behind the ID property. This forced my Getter to look at the private field, determine if it was Guid.Empty, and if so, to generate a new GUID for me.
private Guid id = Guid.Empty;
[Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
[HiddenInput(DisplayValue = false)]
public Guid CompanyId
{
get
{
if(id==Guid.Empty)
id = new Guid();
return id;
}
set { id = value; }
}
Upvotes: 1
Reputation: 9435
DatabaseGenerationOption.Identity should be used for identity column.
Try using DatabaseGenerationOption.Computed instead. It should prevent EF from sending a value when inserting the column, and it should pull the db generated value properly on SaveChanges.
Upvotes: 2