为啥实体框架 6 中仍未实现 ON DELETE SET NULL?有障碍吗?

Posted

技术标签:

【中文标题】为啥实体框架 6 中仍未实现 ON DELETE SET NULL?有障碍吗?【英文标题】:Why is ON DELETE SET NULL still not implemented in the Entity Framework 6? Is there a snag?为什么实体框架 6 中仍未实现 ON DELETE SET NULL?有障碍吗? 【发布时间】:2014-01-22 19:17:51 【问题描述】:

仍然无法首先使用实体​​框架代码配置具有 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");

(示例取自this post。)

我认为这种方法没有问题:加载的子实体将与数据库保持同步,因为 EF 将更新(设置为 null)它们的外键和引用属性,并且数据库中的其他记录受到影响并没有什么害处因为它们还没有被加载。

那么,为什么这个功能仍然缺失呢?是不是有什么隐藏的陷阱?

【问题讨论】:

id 也喜欢看到该功能,但更多的是entityframework.codeplex.com/discussions @philsoady 我在那里找不到主题。添加它似乎很容易:它与级联删除没有太大区别是吗? 这个问题似乎离题了,因为它属于产品的功能请求站点 (data.uservoice.com/forums/…) @GertArnold 如果没有正当理由缺少此功能,除了实体框架团队没有优先考虑它之外,这个问题确实是题外话。 在 EF7 中有一个工作项来实现它。 github.com/aspnet/EntityFramework/issues/333 【参考方案1】:

该功能可能没有实现,因为通常更改只会影响实际在工作单元中的对象。级联不可扩展。

而且我还认为在大多数情况下软删除更好。也许这适合你?

您可能还想研究领域驱动设计。这还包括正确使用工作单元(使用聚合)。

顺便说一句,您的解决方案以种子方法编辑数据库。执行迁移的 Up() 方法可能会更好。

【讨论】:

*该功能可能未实现,因为通常更改仅影响实际在工作单元中的对象。 * 级联删除也是如此,默认情况下由 EF 配置。软删除是另一个争论的话题;-) 那么他们也应该删除级联删除。至少它们是一致的。【参考方案2】:

此功能在 Microsoft.EntityFrameworkCore 版本=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

【讨论】:

以上是关于为啥实体框架 6 中仍未实现 ON DELETE SET NULL?有障碍吗?的主要内容,如果未能解决你的问题,请参考以下文章

为啥使用参数化查询或实体框架会阻止 sql 注入?

为啥实体框架 6.1.3 抛出“无法加载类型‘System.Data.Entity.Infrastructure.TableExistenceChecker’”

实体框架核心级联删除错误

为啥我的模型的“on_delete=models.CASCADE”不生成级联外键约束?

为啥 Eclipselink 不在单向 @ManyToOne 关系中生成 ON DELETE CASCADE 子句?

为啥即使组件的父标签标记为提供者,useContext 在组件中仍返回 null?