首页 > 解决方案 > EF Core - 如何添加不可为空的外键属性?

问题描述

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

我有一Donation堂课...

public class Donation {
  public int Id { get; set; }
  // other properties...
}

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

  public int CurrencyID { get; set; }

  [ForeignKey(nameof(CurrencyID))]
  public virtual Currency Currency { get; set; }

...和下​​面的课程...

public class Currency {
  public int Id { get; set; }
  public string Code { get; set; }
  public string Symbol { get; set; }
  public virtual IEnumerable<Donation> Donations { get; set; }
}

我还填充了Currencies表格...

  builder.Entity<Currency>().HasData(new List<Currency> {
    new Currency { Id = (int)SupportedCurrencies.GBP, Code="GBP", Symbol = "£" },
    new Currency { Id = (int)SupportedCurrencies.EUR, Code="EUR", Symbol = "€" },
    new Currency { Id = (int)SupportedCurrencies.USD, Code="USD", Symbol = "$" },
    //...
  });

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

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

Pre-Core,我会添加一个Currencies表,然后在 SQL 脚本中填充它,然后将列添加到Donations表中,将CurrencyID属性设置为所有现有捐赠的 GBP 的 ID。

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

如何使用 EF Core 迁移执行此操作?

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

标签: entity-frameworkasp.net-coreentity-framework-migrations

解决方案


原来我错过了设置CurrencyID属性的默认值。有点明显,现在我看到了。

我添加了以下...

  builder.Entity<Donation>()
    .Property(p => p.CurrencyID)
    .HasDefaultValue(1);

...并且错误消失了。

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

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

推荐阅读