为什么SET IDENTITY_INSERT OFF不适用于EF 4.1?

时间:2011-10-10 15:05:54

标签: entity-framework ef-code-first

我正在使用Entity Framework 4.1 Code First,我有一个具有IDENTITY键的表,因为此表中的所有新条目都应具有自动生成的ID(ID列称为AccountNumber)。我需要从此系统的先前版本中导入一些数据 - 这些帐号需要保留。

a previous question中,我了解到必须设置IDENTITY_INSERT才能保留旧帐号。我的想法是,在导入旧客户时,我将打开IDENTITY_INSERT,运行原始SQL插入语句,然后将其关闭并使用EF实体正常继续。

所以,我有以下代码:

    public const string InsertQuery = "INSERT INTO dbo.Businesses (AccountNumber, Name, Active, CreatedBy, CreatedOn, ModifiedBy, ModifiedOn) VALUES({0}, {1}, {2}, {3}, {4}, {5}, {6})";

...

            dbContext.Database.ExecuteSqlCommand("SET IDENTITY_INSERT dbo.Businesses ON");
            dbContext.Database.ExecuteSqlCommand(InsertQuery, customerData.AccountNumber, customerData.Name, customerData.Active,
                                                 m_userContextManager.GetCurrentUserName(), Now,
                                                 m_userContextManager.GetCurrentUserName(), Now);
            dbContext.Database.ExecuteSqlCommand("SET IDENTITY_INSERT dbo.Businesses OFF");

            // load the entity and map the rest of the attributes
            dbContext.SaveChanges();

当我执行第二个语句时,我得到以下真气错误(因为我只是将它设置为OFF或者我认为):

Cannot insert explicit value for identity column in table 'Businesses' when IDENTITY_INSERT is set to OFF.

语句的返回值是-1,但由于the documentation on MSDN for ExecuteSqlCommand真的不合适,我不知道这意味着什么。如果声明由于某种原因失败,我希望抛出异常。有谁知道这里发生了什么?

2 个答案:

答案 0 :(得分:11)

没有必要使用普通的旧ADO.NET;诀窍是将所有内容打包成一个命令:

public const string InsertQuery = @"
    SET IDENTITY_INSERT dbo.Businesses ON;
    INSERT INTO dbo.Businesses (AccountNumber, Name, Active, CreatedBy, CreatedOn, ModifiedBy, ModifiedOn) VALUES({0}, {1}, {2}, {3}, {4}, {5}, {6});
    SET IDENTITY_INSERT dbo.Businesses OFF;
";

dbContext.Database.ExecuteSqlCommand(InsertQuery, customerData.AccountNumber, customerData.Name, customerData.Active,
                                     m_userContextManager.GetCurrentUserName(), Now,
                                     m_userContextManager.GetCurrentUserName(), Now);

// load the entity and map the rest of the attributes
dbContext.SaveChanges();

此外,您可以删除SET IDENTITY_INSERT dbo.Businesses OFF(因为IDENTITY_INSERT在命令末尾已关闭)和dbContext.SaveChanges(),因为ExecuteSqlCommand会立即执行命令;它不等待SaveChanges()。

答案 1 :(得分:5)

ExecuteSqlCommand将打开连接,执行sql然后关闭它。所以你的下一个命令将使用不同的连接执行。

您可以使用普通的旧ADO.net类在单个事务中插入数据。或者编写数据脚本并将其作为shown here

执行