I made a few tables in EF and entered in some seed data where I give value to a few columns with a primary key. When I run the application I am getting the error message: <
Another way is to explicitly open a connection then SET IDENTITY_INSERT <table> ON
.
var conn = context.Database.GetDbConnection();
if (conn.State != ConnectionState.Open)
conn.Open();
context.Database.ExecuteSqlCommand("SET IDENTITY_INSERT Posts ON");
var post = new WeblogPost()
{
Id= oldPost.Pk, // <!--- explicit value to Id field
Title = oldPost.Title,
...
};
context.Posts.Add(post);
conn.Close();
Apparently once a connection has been explicitly opened before an EF request, that connection is not automatically closed by EF, so the setting is applied to the same connection context.
This is the same reason that Steve's response with transactions works as transactions keep a connection alive.
Note: you don't want to put the connection into a
using
statement if you plan to use the same context again later in the application/request. The connection has to exist, so the best way to clear the connection context is to.Close()
it, thereby returning EF to its default behavior of opening and closing the connection per operation.
In EF Core 1.1.2, I got this to work with transactions. In my "database initializer" that put seed data into the tables. I used the technique from this EF6 answer. Here's a sample of the code:
using (var db = new AppDbContext())
using (var transaction = db.Database.BeginTransaction())
{
var user = new User {Id = 123, Name = "Joe"};
db.Users.Add(user);
db.Database.ExecuteSqlCommand("SET IDENTITY_INSERT MyDB.Users ON;");
db.SaveChanges();
db.Database.ExecuteSqlCommand("SET IDENTITY_INSERT MyDB.Users OFF");
transaction.Commit();
}
Another way is to use ExecuteSqlRaw. Unlike ExecuteSqlInterpolated, you do not have to convert your passed string to a formattable string type.
using (var db = new AppDbContext())
using (var transaction = db.Database.BeginTransaction())
{
var user = new User {Id = 123, Name = "Joe"};
db.Users.Add(user);
db.Database.ExecuteSqlRaw("SET IDENTITY_INSERT MyDB.Users ON");
db.SaveChanges();
db.Database.ExecuteSqlRaw("SET IDENTITY_INSERT MyDB.Users OFF");
transaction.Commit();
` }
In order to add related entities with an object graph using the DbContext
I used a DbCommandInterceptor
which automatically sets INSERT_IDENTITY ON
for the table in question and then OFF
after the insert. This works with IDs manually set and DbContext.SaveChanges
. I used it in my integration tests but after a performance optimization maybe it could be suitable for production code in some cases. Here is my answer to a similar SO question which explains the details.
Use "SET IDENTITY_INSERT [table] ON/OFF" into transaction
public static void TranslateDatabase(ref BDVContext bdvContext)
{
bdvContext.Foro.RemoveRange(bdvContext.Foro);
bdvContext.SaveChanges();
using (var transaction = bdvContext.Database.BeginTransaction())
{
bdvContext.Database.ExecuteSqlRaw("SET IDENTITY_INSERT [dbo].[Foro] On");
using (old_balsaContext db = new old_balsaContext())
{
long id = 0;
foreach (ForoA77 post in db.ForoA77.Where(x => x.Fecha > new DateTime(2000,1,1) & x.IdPadre == 0 ) )
{
bdvContext.Foro.Add(new Foro
{
Id = ++id
, ParentId = 0
, EditId = 0
, IdDomains = 2
, UserNick = post.IdUsuario == 1 ? bdvContext.Users.Where(x => x.Id == 2).Single().User : post.Nick?? ""
, IdUsers = post.IdUsuario == 1 ? (int?)2 : null
, Title = post.Asunto?? ""
, Text = post.Texto?? ""
, Closed = post.Cerrado?? false
, Banned = post.Veto?? false
, Remarqued = post.Remarcado?? false
, Deleted = false
, Date = post.Fecha?? new DateTime(2001,1,1)
});
}
}
bdvContext.SaveChanges();
bdvContext.Database.ExecuteSqlRaw("SET IDENTITY_INSERT [dbo].[Foro] Off");
transaction.Commit();
}
}
Note, my entityframework was generated by reverse engineering
Below solution worked for me.(Link)
I have added below annotations. and removed [Key]
Annotation.
[KeyAttribute()]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Id { get; set; }
Namespace can be changed according to the entity framework version. For Entity framework core namespace is System.ComponentModel.DataAnnotations.Schema
I did not face a data migration since I have tried in a new project.