【问题标题】:EF Core - code first - multiple cascade pathsEF Core - 代码优先 - 多个级联路径
【发布时间】:2018-08-03 12:26:17
【问题描述】:

我知道关于这个主题的文章很多,所以我先说我仔细阅读了Google about this topic 的前两页。

很多人建议放DeleteBehavior.Restrictdotnet ef database update 不再抱怨了。在您尝试删除记录之前,问题已解决。

我遇到了与this SO question 完全相同的问题,这与this one 重复。第二个链接中提出的解决方案是:

你应该打破这个循环。您可以通过关闭来做到这一点 级联删除(通过在 各自的关系配置)至少其中之一 关系客户->付款或客户->计费中心。

这是我目前研究的内容。
现在让我们(再次)解决问题。我有钻石关系:

所有外键必须是not null。因此,设置一个外键以允许 null 不是一种选择。我还希望该用户可以删除:

  • Parameter-Value-Parts -> 没问题
  • 参数值->这里没问题 OnDelete(DeleteBehavior.Cascade)
  • 参数-零件->这里没问题 OnDelete(DeleteBehavior.Cascade)
  • 参数 -> 大问题

要关注answer on this SO question,我可以用OnDelete(DeleteBehavior.Restrict) 打破Parameter-PartsParameter-Value-Parts 之间的循环。
这将允许我删除Parameter,但现在我无法删除Parameter-Parts

我可以在删除Parameter-Parts之前手动删除所有Parameter-Value-Parts,但我想避免手动删除。这可能吗?

我还阅读了 SO,应避免在应用程序中使用所有 cascade delete,开发人员应在删除行之前手动删除相关表行。什么是最佳实践?
删除级联似乎很容易解决,但我不是在寻找一个简单的解决方案,而是寻找正确的解决方案。在大型应用程序中的大型数据模型上轻松扩展的一种。

【问题讨论】:

  • 真正的钻石关系不适用于简单的 ID 密钥,但据我所知,它们会带有一些共享密钥部分......

标签: sql-server entity-framework foreign-keys entity-framework-core cascading-deletes


【解决方案1】:

希望我能正确理解您的要求。

如果您想要一个真正的菱形,那么ParameterValueParts 需要引用ParameterValuesParameterParts,而ParameterParts 又引用相同的Parameter。这将由 SQL 中的复合键建模:

class Parameter
{
    public int ParameterId { get; set; }
}

class ParameterValue
{
    // composite key of ParameterId, ValueId with ParameterId also being a foreign key
    public int ParameterId { get; set; }
    public int ValueId { get; set; }
}

class ParameterPart
{
    // composite key of ParameterId, PartId with ParameterId also being a foreign key
    public int ParameterId { get; set; }
    public int PartId { get; set; }
}

class ParameterValueParts
{
    // key
    public int Id { get; set; }

    // three foreign keys:
    // ParameterId as foreign key to Parameter
    // ParameterId, ValueId are the composite foreign key to ParameterValue
    // ParameterId, PartId are the composite foreign key to ParameterPart
    public int ParameterId { get; set; }
    public int ValueId { get; set; }
    public int PartId { get; set; }
}

这样,您可以拥有ParameterValueParameterPart 的多种组合,但每个组合都必须属于特定的Parameter。使用这种基本设计,我的项目中从未遇到过任何级联问题。

旁注:您可以在各自的类中将ValueIdPartId 配置为DatabaseGeneratedOption.Identity,以免手动处理ID 值。 (至少在 EF6 中,我希望 EF Core 在这方面工作类似)

【讨论】:

    猜你喜欢
    • 2021-10-17
    • 2015-05-17
    • 1970-01-01
    • 1970-01-01
    • 2019-09-22
    • 1970-01-01
    • 2011-07-19
    • 2012-02-06
    相关资源
    最近更新 更多