我正在进行一小组表的数据迁移。密钥当然在源数据库中有所体现,我编写了与此类似的初始化语句:
context.Countries.Add(new Country{CountryId=75,CountryName="US"});
context.Countries.Add(new Country{CountryId=89,CountryName="Argentina"});
然而,当我在数据库中查看之后,我发现了这个:
CountryID | CountryName
------------------------
1 | US
2 | Argentina
(它忽略了我提供的CountryIds并为此标识列使用了n + 1个值。)
为了解决这个问题,我尝试了这个:
context.Database.ExecuteSqlCommand("Set IDENTITY_INSERT COUNTRIES ON");
GetCountries().ForEach(c=>context.Countries.Add(c));
context.Database.ExecuteSqlCommand("Set IDENTITY_INSERT COUNTRIES OFF");
但我发现db中的键没有区别。
如何从我的初始化程序的Seed()方法中进行标识插入?
编辑:
我发布了我最后一次尝试的结果,以便其他任何人受益:
private void InsertCountries(SodContext context)
{
context.Database.ExecuteSqlCommand("Set IDENTITY_INSERT COUNTRIES ON");
string cmd = "INSERT INTO COUNTRIES (CountryId,Name,IsActive) values ({0},'{1}',{2})";
GetCountries().ForEach(cntry=>context.Database.ExecuteSqlCommand(string.Format(cmd,cntry.CountryId,cntry.Name,cntry.IsActive==false?0:1)));
context.Database.ExecuteSqlCommand("Set IDENTITY_INSERT COUNTRIES OFF");
}
但是,我收到错误消息,我必须打开IDENTITY_INSERT。
我放弃并转而在TSQL脚本中执行此操作。
答案 0 :(得分:1)
如果已将主键属性配置为数据库生成的标识(即:自动增量),则EF将不会在发出的insert语句中包含该列。因此EF将请求生成的密钥并更新主键属性。
您可以做的是编写必要的数据并直接执行该脚本,而无需使用实体。
答案 1 :(得分:0)
我参加了你在c#代码中尝试的内容。 将所有内容放在相同的sql命令语句中确实有效。
const string sqlCmd = "set identity_insert [role] on insert into [role](id, name) values({0}, {1}) set identity_insert [role] off";
context.Database.ExecuteSqlCommand(sqlCmd,(int)SystemRole.SuperAdministrator, superAdminRole);
context.Database.ExecuteSqlCommand(sqlCmd, (int)SystemRole.Administrator, adminRole);
context.Database.ExecuteSqlCommand(sqlCmd, (int)SystemRole.Manager, managerRole);
context.Database.ExecuteSqlCommand(sqlCmd, (int)SystemRole.User, userRole);