I have an entity that has an Auto-identity (int)
column. As part of the data-seed I want to use specific identifier values for the "standard data" in my system, after that I want to have the database to sort out the id value.
So far I've been able to set the IDENTITY_INSERT
to On as part of the insert batch, but Entity Framework does not generate an insert statement that include the Id
. This makes sense as the model thinks the database should provide the value, but in this case I want to provide the value.
Model (pseudo code):
public class ReferenceThing
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id{get;set;}
public string Name{get;set;}
}
public class Seeder
{
public void Seed (DbContext context)
{
var myThing = new ReferenceThing
{
Id = 1,
Name = "Thing with Id 1"
};
context.Set<ReferenceThing>.Add(myThing);
context.Database.Connection.Open();
context.Database.ExecuteSqlCommand("SET IDENTITY_INSERT ReferenceThing ON")
context.SaveChanges(); // <-- generates SQL INSERT statement
// but without Id column value
context.Database.ExecuteSqlCommand("SET IDENTITY_INSERT ReferenceThing OFF")
}
}
Anyone able to offer any insight or suggestions?
So I might have resolved this one by resorting to generating my own SQL insert statements that include the Id column. It feels like a terrible hack, but it works :-/
public class Seeder
{
public void Seed (DbContext context)
{
var myThing = new ReferenceThing
{
Id = 1,
Name = "Thing with Id 1"
};
context.Set<ReferenceThing>.Add(myThing);
context.Database.Connection.Open();
context.Database.ExecuteSqlCommand("SET IDENTITY_INSERT ReferenceThing ON")
// manually generate SQL & execute
context.Database.ExecuteSqlCommand("INSERT ReferenceThing (Id, Name) " +
"VALUES (@0, @1)",
myThing.Id, myThing.Name);
context.Database.ExecuteSqlCommand("SET IDENTITY_INSERT ReferenceThing OFF")
}
}