C# 英孚核心;无法为标识列“插入显式值”;虽然IDENTIY_INSERT设置为ON

C# 英孚核心;无法为标识列“插入显式值”;虽然IDENTIY_INSERT设置为ON,c#,sql-server,entity-framework-core,C#,Sql Server,Entity Framework Core,我正在使用EntityFrameworkCore2.1,希望使用IDENTITY\uInsert插入一些数据。 虽然我将IDENTITY_INSERT设置为On,但在identityContext.SaveChanges()行中仍然出现异常: Microsoft.EntityFrameworkCore.DbUpdateException:'发生错误 在更新条目时。有关详细信息,请参阅内部异常。” 内部异常 SqlException:无法为插入显式值 当identity_INSERT设置为时,表“

我正在使用EntityFrameworkCore2.1,希望使用IDENTITY\uInsert插入一些数据。 虽然我将IDENTITY_INSERT设置为On,但在
identityContext.SaveChanges()行中仍然出现异常

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

内部异常

SqlException:无法为插入显式值 当identity_INSERT设置为时,表“ClientGroups”中的identity列 走开

这是我的代码:

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)[参数=[],命令类型='Text',命令超时='30'] 设置标识\u在以下信息上插入dbo.ClientGroups:Microsoft.EntityFrameworkCore.Database.Command[20101] 已执行的DbCommand(0ms)[参数=[],命令类型='Text',命令超时='30'] 设置标识\u在信息上插入dbo.Clients:Microsoft.EntityFrameworkCore.Database.Command[20101] 已执行的DbCommand(0ms)[参数=[],命令类型='Text',命令超时='30'] 设置标识\u在以下信息上插入dbo.ModulePermissions:Microsoft.EntityFrameworkCore.Database.Command[20101] 已执行的DbCommand(0ms)[参数=[],命令类型='Text',命令超时='30'] SET IDENTITY\u INSERT dbo.Roles ON info:Microsoft.EntityFrameworkCore.Database.Command[20101] 已执行的DbCommand(0ms)[参数=[],命令类型='Text',命令超时='30'] 在上设置IDENTITY_INSERT dbo.Users


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

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

identityContext.Database.OpenConnection();
try
{
    // your code …
}    
finally
{
    identityContext.Database.CloseConnection();
}
或者将整个流程包装在显式事务中:

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

这是一个混合的评论@damien的不信者和建议的答案@ivan stoev

  • 一次只能为一个表启用IDENTITY_INSERT
  • 代码必须包装在事务中,否则EF Core将使用单独的连接
  • 这是密码

    using (var identityContext = new IdentityDatabase(identityOptions))
    {
        using (var transaction = identityContext.Database.BeginTransaction())
        {
            Console.WriteLine("Inserting 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();
        }
    }
    

    您的表在sql server中真的是这样命名的吗在任何时候,会话中只有一个表的IDENTITY_INSERT属性可以设置为ON。如果一个表已将此属性设置为“开”,并且为另一个表发出了set IDENTITY_INSERT ON语句,SQL Server将返回一条错误消息,说明set IDENTITY_INSERT已打开,并报告为“”设置的表。您的代码无法按编写的方式工作。