防止导致“循环或多个级联路径”的CASCADE DELETE

时间:2014-01-28 00:34:46

标签: entity-framework ef-code-first entity-framework-5

我有像

这样的关系
public class Widget
{
    public virtual int Id { get; set; }
    public virtual string Text { get; set; }
}

public class WidgetPair
{
    public virtual int Id { get; set; }

    public virtual Widget WidgetA { get; set; }
    public virtual int WidgetAId { get; set; }

    public virtual Widget WidgetB { get; set; }
    public virtual int WidgetBId { get; set; }
}

请注意,Widget在对象模型中没有WidgetPair的概念。

当我尝试使用EF Code First迁移更新我的数据库时,出现错误

  

在表'WidgetPairs'上引入FOREIGN KEY约束'FK_dbo.WidgetPairs_dbo.Widget_WidgetAId'可能会导致循环或多个级联路径

有道理,因为SQL Server不喜欢two properties from the table pointing to the same parent

理想的行为是,如果给定的WidgetPair.WidgetA(或.WidgetB)指向随后删除的特定Widget,则WidgetA(或WidgetB)将变为null。

我不想在Widget表或WidgetPairs表中删除删除另一个表中的行。

似乎我可以使用流畅的界面配置它,但我无法确切地知道如何做到这一点。如果我想从Widget添加一个引用到WidgetPair(我做),以下似乎可以工作:

modelBuilder.Entity<WidgetPair>().HasOptional(p => p.WidgetA)
  .WithMany(q => q.TheChildWidget)
  .WillCascadeOnDelete(false);

这不起作用,因为单个Widget可以参与许多WidgetPairs。此外,Widget没有域名要求直接知道它参与的WidgetPairs。

是否可以配置此行为?怎么样?

1 个答案:

答案 0 :(得分:0)

事实证明,通过使用类型 int 作为外键,我将从WidgetPair到Widget的关系变为非可空。这反过来导致级联删除。

将类型更改为 int?可解决此问题:

public virtual Widget WidgetA { get; set; }
public virtual int? WidgetAId { get; set; }