无法先使用实体框架代码配置与 ON DELETE SET NULL 规则的关系。解决方法是将所有相关实体加载到内存中,然后在删除父实体时,EF 将发出 SQL 命令以将其外键设置为 Null。
这,虽然使用以下内容自己实现这一点是微不足道的:
protected override void Seed(Context context)
{
context.Database.ExecuteSqlCommand("ALTER TABLE dbo.Guests DROP CONSTRAINT Guest_PreferredLanguage");
context.Database.ExecuteSqlCommand("ALTER TABLE dbo.Guests ADD CONSTRAINT Guest_PreferredLanguage FOREIGN KEY (LanguageID) REFERENCES dbo.Languages(LanguageID) ON UPDATE NO ACTION ON DELETE SET NULL");
}
(示例取自这篇文章。
我认为这种方法没有问题:加载的子实体将与数据库保持同步,因为 EF 将更新(设置为 null)其外键和引用属性,并且数据库中的其他记录受到影响不会造成伤害,因为它们无论如何都没有加载。
那么,为什么这个功能仍然缺失呢?有什么隐藏的障碍吗?
该功能可能没有实现,因为通常更改只影响实际在工作单元中的对象。级联不可扩展。
而且我也认为在大多数情况下软删除更好。也许这是给你的东西?
您可能还想研究领域驱动设计。这也包括工作单元(带有聚合)的正确使用。
顺便说一句,您的解决方案在种子方法中编辑数据库。最好使用 Up() 迁移方法执行此操作。
在 Microsoft.EntityFrameworkCore Version=3.1.10.0 及更高版本中可用。
modelBuilder.Entity<Guests>()
.HasOne<Languages>(g => g.Language)
.WithMany(l => l.Guests)
.HasForeignKey(g => g.LanguageID)
.IsRequired(false)
.OnDelete(DeleteBehavior.SetNull);
注意,DeleteBehavior.SetNull