我知道很多关于这个主题的文章,所以我先说一下我在Google about this topic上仔细阅读前2页。
许多人建议放DeleteBehavior.Restrict
,而dotnet ef database update
不再抱怨。在您尝试删除记录之前问题已解决。
我遇到与this SO question完全相同的问题,该问题与this one重复。第二个链接中提出的解决方案是:
你应该打破这个循环。你可以通过关闭来做到这一点 级联删除(通过包含WillCascadeOnDelete(false)) 对于至少一个的相应关系配置) 关系客户 - >付款或客户 - > billingCenters。
这是我到目前为止研究的内容 现在让我们再次解决问题。我有钻石关系:
所有ForeignKeys必须为not null
。因此,设置一个外键以允许null不是一种选择。我还希望该用户可以删除:
OnDelete(DeleteBehavior.Cascade)
OnDelete(DeleteBehavior.Cascade)
要关注answer on this SO question,我可以使用Parameter-Parts
在Parameter-Value-Parts
和OnDelete(DeleteBehavior.Restrict)
之间打破周期。
这样我就可以删除Parameter
,但现在我无法删除Parameter-Parts
。
我可以在删除Parameter-Value-Parts
之前手动删除所有Parameter-Parts
,但我希望避免手动删除。这可能吗?
我还在SO上读到,在应用程序中应该避免所有cascade delete
,并且开发人员应该在删除行之前手动处理删除依赖表行。什么是最佳实践?
删除级联似乎很容易解决,但我不是在寻找一个简单的解决方案,而是正确的解决方案。在大型应用程序中可以轻松扩展到大型数据模型的那个。
答案 0 :(得分:2)
我希望我能正确理解你的要求。
如果你想要一个真正的钻石形状,那么ParameterValueParts
需要引用ParameterValues
和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; }
}
这样,您可以拥有ParameterValue
和ParameterPart
的多种组合,但每种组合都必须属于特定的Parameter
。有了这个基本设计,我的项目中从未遇到任何级联问题。
附注:您可以在各自的类中将ValueId
和PartId
配置为DatabaseGeneratedOption.Identity
,以便不手动处理ID值。 (至少在EF6中,我希望EF Core在这方面的工作方式类似)