我正在使用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真的不合适,我不知道这意味着什么。如果声明由于某种原因失败,我希望抛出异常。有谁知道这里发生了什么?
答案 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
执行