Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does this EF insert with IDENTITY_INSERT not work?

This is the query:

using (var db = new AppDbContext())
{
    var item = new IdentityItem {Id = 418, Name = "Abrahadabra" };
    db.IdentityItems.Add(item);
    db.Database.ExecuteSqlCommand("SET IDENTITY_INSERT Test.Items ON;");
    db.SaveChanges();
}

When executed, the Id of the inserted record, on a new table, is still 1.

NEW: When I use either the transaction, or TGlatzer's answer, I get the exception:

Explicit value must be specified for identity column in table 'Items' either when IDENTITY_INSERT is set to ON or when a replication user is inserting into a NOT FOR REPLICATION identity column.

like image 302
ProfK Avatar asked Feb 02 '17 06:02

ProfK


People also ask

How do you on IDENTITY_INSERT is set to ON?

If the value inserted is larger than the current identity value for the table, SQL Server automatically uses the new inserted value as the current identity value. The setting of SET IDENTITY_INSERT is set at execute or run time and not at parse time.

Do I need to set IDENTITY_INSERT off?

Set IDENTITY_INSERT on for all tables You will get an error that the other table is using this option if you try to set this option to ON in more than one table. It will also tell you the name of the table which is using this option. Therefore, you should always set this option to OFF after inserting the rows.

What does IDENTITY_INSERT mean?

IDENTITY_INSERT is a table property that allows you to insert explicit values into the column of table identifiers, i.e. into the column with IDENTITY. The value of the inserted identifier can be either less than the current value or more, for example, to skip a certain interval of values.


2 Answers

I did not honor the tags of the question telling this is about EF6.
This answer will work for EF Core

The real culprit here is not the missing transaction, but the small inconvenience, that Database.ExectueSqlCommand() will not keep the connection open, when not explicitly opened before.

using (var db = new AppDbContext())
{
    var item = new IdentityItem {Id = 418, Name = "Abrahadabra" };
    db.IdentityItems.Add(item);
    db.Database.OpenConnection();
    db.Database.ExecuteSqlCommand("SET IDENTITY_INSERT Test.Items ON;");
    db.SaveChanges();
}

will also do, since SET IDENTITY_INSERT [...] ON/OFF will be bound to your connection.

like image 68
TGlatzer Avatar answered Sep 24 '22 16:09

TGlatzer


According to this previous Question you need to begin a transaction of your context. After saving the change you have to restate the Identity Insert column too and finally you must have to commit the transaction.

using (var db = new AppDbContext())
using (var transaction = db .Database.BeginTransaction())
{
    var item = new IdentityItem {Id = 418, Name = "Abrahadabra" };
    db.IdentityItems.Add(item);
    db.Database.ExecuteSqlCommand("SET IDENTITY_INSERT Test.Items ON;");
    db.SaveChanges();
    db.Database.ExecuteSqlCommand("SET IDENTITY_INSERT Test.Items OFF");
    transaction.Commit();
}
like image 26
gdmanandamohon Avatar answered Sep 24 '22 16:09

gdmanandamohon