EF CodeFirst 初始化程序 - 无法设置 PK 值

发布于 2024-12-08 19:30:28 字数 1391 浏览 0 评论 0原文

我正在对一小组表进行数据迁移。这些键当然在源数据库中进行了修改,并且我编写了与此类似的初始化语句:

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");

但是我发现数据库中的键没有任何区别。

如何从初始化程序的 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 ON。

我放弃并转而使用 TSQL 脚本执行此操作。

I'm doing a data migration of a small set of tables. The keys are of course alinged in the source database and I have composed initialization statements similar to this one:

context.Countries.Add(new Country{CountryId=75,CountryName="US"});
context.Countries.Add(new Country{CountryId=89,CountryName="Argentina"});

However, when I look in the database afterwards I find this:

CountryID | CountryName
------------------------
1         | US
2         | Argentina

(It disregards the CountryIds I provide and uses n+1 values for this identity column.)

In an effort to solve the problem I tried this:

context.Database.ExecuteSqlCommand("Set IDENTITY_INSERT COUNTRIES ON");            
GetCountries().ForEach(c=>context.Countries.Add(c));
context.Database.ExecuteSqlCommand("Set IDENTITY_INSERT COUNTRIES OFF");

But I see no difference in the keys in the db.

How do I do an Identity Insert from my Initializer's Seed() method?

EDIT:

I'm posting the results of my final attempt for the benefit of anyone else following after:

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");            
    }

However, I get the error message that I have to turn IDENTITY_INSERT ON.

I'm giving up and switching over to doing this in a TSQL script.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

御守 2024-12-15 19:30:28

如果您已将主键属性配置为数据库生成的标识(即:自动增量),则 EF 将不会在发出的插入语句中包含该列。因此 EF 将请求生成的密钥并更新主键属性。

您可以做的是编写必要的数据脚本并直接执行该脚本而不使用实体。

If you have configured your primary key properties as database generated identities(ie: Auto increment) then EF will not include that column in the insert statements that are issued. So EF will request the generated key and update the primary key property.

What you can do is script the necessary data and execute that script directly without using entities.

万劫不复 2024-12-15 19:30:28

我尝试了您在 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);

I had a go at what you were trying in the c# code.
Putting everything in the same sql command statement does work.

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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文