EF Core - 如何添加不可为空的外键属性?

Dre*_*eep 5 entity-framework asp.net-core entity-framework-migrations

VS2019 中的 ASP.NET ASP Core 2.2 和 EF。

\n\n

我有Donation课...

\n\n
public class Donation {\n  public int Id { get; set; }\n  // other properties...\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

到目前为止,所有捐款都被假定为英镑。我们想要添加对其他货币的支持,因此想要添加一个Currency类(最终会成为一个表),并有一个从到 的Currencies外键链接。我将以下代码添加到...DonationCurrencyDonation

\n\n
  public int CurrencyID { get; set; }\n\n  [ForeignKey(nameof(CurrencyID))]\n  public virtual Currency Currency { get; set; }\n
Run Code Online (Sandbox Code Playgroud)\n\n

...以及下面的课程...

\n\n
public class Currency {\n  public int Id { get; set; }\n  public string Code { get; set; }\n  public string Symbol { get; set; }\n  public virtual IEnumerable<Donation> Donations { get; set; }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

我还填充了Currencies表...

\n\n
  builder.Entity<Currency>().HasData(new List<Currency> {\n    new Currency { Id = (int)SupportedCurrencies.GBP, Code="GBP", Symbol = "\xc2\xa3" },\n    new Currency { Id = (int)SupportedCurrencies.EUR, Code="EUR", Symbol = "\xe2\x82\xac" },\n    new Currency { Id = (int)SupportedCurrencies.USD, Code="USD", Symbol = "$" },\n    //...\n  });\n
Run Code Online (Sandbox Code Playgroud)\n\n

但是,这在更新数据库时出现错误,因为它试图将 的值设置CurrencyID为 null。

\n\n

我尝试添加两个迁移,一个具有可为空的CurrencyID属性,第二个具有非空属性,希望数据库更新可以运行代码来填充Currencies之间的表,但这也不起作用。我遇到了同样的错误,无法将CurrencyID属性的值设置为 null,因为它不可为 null。

\n\n

在核心之前,我会添加一个Currencies表,然后在 SQL 脚本中填充它,然后将列添加到表中Donations,将CurrencyID属性设置为所有现有捐赠的英镑 ID。

\n\n

需要澄清的是,该CurrencyID财产应该是不可为空的,因为每笔捐赠都必须采用某种货币。

\n\n

如何通过 EF Core 迁移执行此操作?

\n\n

几年前有人问过同样的问题,但没有得到答案。

\n

Dre*_*eep 2

事实证明我错过了设置该CurrencyID属性的默认值。现在我明白了。

我添加了以下内容...

  builder.Entity<Donation>()
    .Property(p => p.CurrencyID)
    .HasDefaultValue(1);
Run Code Online (Sandbox Code Playgroud)

...错误消失了。

顺便说一句,这给了我一个关于导致循环或多个级联路径的不同错误。我通过修改Up迁移中的方法,设置为onDeleteRestrict不是默认值来解决这个问题Default......

        migrationBuilder.AddForeignKey(
            name: "FK_Donations_Currencies_CurrencyID",
            table: "Donations",
            column: "CurrencyID",
            principalTable: "Currencies",
            principalColumn: "Id",
            onDelete: ReferentialAction.Restrict);
Run Code Online (Sandbox Code Playgroud)