EF核心“无法为标识列插入显式值”,尽管IDENTIY_INSERT设置为ON

时间:2018-08-13 11:25:01

标签: c# sql-server entity-framework-core

我正在使用Entity Framework Core 2.1,并希望使用IDENTITY_INSERT插入一些数据。 尽管我将IDENTITY_INSERT设置为On,但在行identityContext.SaveChanges();上仍然出现异常:

  

Microsoft.EntityFrameworkCore.DbUpdateException:'发生了错误   在更新条目时。有关详细信息,请参见内部异常。'

     

内部异常

     

SqlException:无法为以下项插入显式值   IDENTITY_INSERT设置为'ClientGroups'表中的标识列   关闭。

这是我的代码:

using (var identityContext = new IdentityDatabase(identityOptions))
{
    Console.WriteLine("Settings Identity Insert on");
    identityContext.Database.ExecuteSqlCommand("SET IDENTITY_INSERT dbo.ClientGroups ON");
    identityContext.Database.ExecuteSqlCommand("SET IDENTITY_INSERT dbo.Clients ON");
    identityContext.Database.ExecuteSqlCommand("SET IDENTITY_INSERT dbo.ModulePermissions ON");
    identityContext.Database.ExecuteSqlCommand("SET IDENTITY_INSERT dbo.Roles ON");
    identityContext.Database.ExecuteSqlCommand("SET IDENTITY_INSERT dbo.Users ON");

    identityContext.Clients.AddRange(identityclients);
    identityContext.ClientGroups.AddRange(identityClientGroups);
    identityContext.ClientGroupAssociations.AddRange(identityClientGroupAssociations);
    identityContext.AuthClients.AddRange(identityAuthClients);
    identityContext.Roles.AddRange(identityRoles);
    identityContext.Users.AddRange(identityUsers);
    identityContext.UserRoles.AddRange(identityUserRoles);
    identityContext.ModulePermissions.AddRange(identityModulePermissions);
    Console.WriteLine("Saving Data to .identity Database");
    identityContext.SaveChanges();

    Console.WriteLine("Setting Identity Insert off");
    identityContext.Database.ExecuteSqlCommand("SET IDENTITY_INSERT dbo.ClientGroups OFF");
    identityContext.Database.ExecuteSqlCommand("SET IDENTITY_INSERT dbo.Clients OFF");
    identityContext.Database.ExecuteSqlCommand("SET IDENTITY_INSERT dbo.ModulePermissions OFF");
    identityContext.Database.ExecuteSqlCommand("SET IDENTITY_INSERT dbo.Roles OFF");
    identityContext.Database.ExecuteSqlCommand("SET IDENTITY_INSERT dbo.Users OFF");
}

我打开了登录功能,可以看到命令已发送到数据库:

  

信息:Microsoft.EntityFrameworkCore.Database.Command [20101]         执行的DbCommand(1ms)[Parameters = [],CommandType ='Text',CommandTimeout = '30']         SET IDENTITY_INSERT dbo.ClientGroups ON信息:Microsoft.EntityFrameworkCore.Database.Command [20101]         已执行DbCommand(0ms)[Parameters = [],CommandType ='Text',CommandTimeout = '30']         SET IDENTITY_INSERT dbo.Clients上的信息:Microsoft.EntityFrameworkCore.Database.Command [20101]         已执行DbCommand(0ms)[Parameters = [],CommandType ='Text',CommandTimeout = '30']         SET IDENTITY_INSERT dbo.ModulePermissions ON信息:Microsoft.EntityFrameworkCore.Database.Command [20101]         已执行DbCommand(0ms)[Parameters = [],CommandType ='Text',CommandTimeout = '30']         SET IDENTITY_INSERT dbo.Roles ON信息:Microsoft.EntityFrameworkCore.Database.Command [20101]         已执行DbCommand(0ms)[Parameters = [],CommandType ='Text',CommandTimeout = '30']         设置IDENTITY_INSERT dbo。用户开启

2 个答案:

答案 0 :(得分:1)

EF Core为每个与数据库相关的操作打开/关闭连接,因此使用ExecuteSqlCommand设置身份无效。

您需要在整个过程中明确保持连接打开:

identityContext.Database.OpenConnection();
try
{
    // your code …
}    
finally
{
    identityContext.Database.CloseConnection();
}

或将整个过程包装在显式事务中:

using (var transaction = identityContext.Database.BeginTransaction())
{
    // your code …
    transaction.Commit();
}

答案 1 :(得分:0)

这是@ damien-the-unbeliever的评论和@ivan stoev的建议答案的组合

  1. 您一次只能为一张桌子打开IDENTITY_INSERT
  2. 必须将代码包装在事务中,因为否则EF Core将使用单独的连接。

    使用(var identityContext = new IdentityDatabase(identityOptions)) {     使用(var transaction = identityContext.Database.BeginTransaction())     {         Console.WriteLine(“插入AuthClients”);         identityContext.AuthClients.AddRange(identityAuthClients);         identityContext.SaveChanges();

        Console.WriteLine("Inserting ClientGroups");
        identityContext.Database.ExecuteSqlCommand("SET IDENTITY_INSERT dbo.ClientGroups ON");
        identityContext.ClientGroups.AddRange(identityClientGroups);
        identityContext.SaveChanges();
        identityContext.Database.ExecuteSqlCommand("SET IDENTITY_INSERT dbo.ClientGroups OFF");
    
        Console.WriteLine("Inserting Clients");
        identityContext.Database.ExecuteSqlCommand("SET IDENTITY_INSERT dbo.Clients ON");
        identityContext.Clients.AddRange(identityclients);
        identityContext.SaveChanges();
        identityContext.Database.ExecuteSqlCommand("SET IDENTITY_INSERT dbo.Clients OFF");
    
        Console.WriteLine("Inserting ClientGroupAssociations");
        identityContext.ClientGroupAssociations.AddRange(identityClientGroupAssociations);
        identityContext.SaveChanges();
    
        Console.WriteLine("Inserting Users");
        identityContext.Database.ExecuteSqlCommand("SET IDENTITY_INSERT dbo.Users ON");
        identityContext.Users.AddRange(identityUsers);
        identityContext.SaveChanges();
        identityContext.Database.ExecuteSqlCommand("SET IDENTITY_INSERT dbo.Users OFF");
    
        Console.WriteLine("Inserting Roles");
        identityContext.Database.ExecuteSqlCommand("SET IDENTITY_INSERT dbo.Roles ON");
        identityContext.Roles.AddRange(identityRoles);
        identityContext.SaveChanges();
        identityContext.Database.ExecuteSqlCommand("SET IDENTITY_INSERT dbo.Roles OFF");
    
        Console.WriteLine("Inserting UserRoles");
        identityContext.UserRoles.AddRange(identityUserRoles);
        identityContext.SaveChanges();
    
        Console.WriteLine("Inserting ModulePermissions");
        identityContext.Database.ExecuteSqlCommand("SET IDENTITY_INSERT dbo.ModulePermissions ON");
        identityContext.ModulePermissions.AddRange(identityModulePermissions);
        identityContext.SaveChanges();
        identityContext.Database.ExecuteSqlCommand("SET IDENTITY_INSERT dbo.ModulePermissions OFF");
    
        Console.WriteLine("Commiting transaction");
        transaction.Commit();
    }
    

    }