删除记录并将外键设置为null时,Entity Framework是否支持?

时间:2014-07-31 10:00:25

标签: entity-framework

我有一个这样的模型:

public class Account
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int? ParentId { get; set; }
    public Account Parent { get; set; }
}

我添加了以下配置:

    this.HasOptional(item => item.Parent)
        .WithMany()
        .HasForeignKey(item => item.ParentId)
        .WillCascadeOnDelete(true);

然后我收到以下错误消息:

  

装配初始化方法   UnitTest.Biz.Accounting.TestInitializer.Init抛出异常。   System.Data.SqlClient.SqlException:   System.Data.SqlClient.SqlException:介绍FOREIGN KEY约束   桌上的'FK_dbo.acct_Account_dbo.acct_Account_ParentId'   'acct_Account'可能会导致循环或多个级联路径。指定ON   DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY   限制。无法创建约束。

我已经阅读了EF的文件,但我不明白我的代码在哪里出错......

  

如果依赖实体上的外键可以为空,则Code First会这样做   没有在关系上设置级联删除,当主体是   删除外键将被设置为null   http://msdn.microsoft.com/en-us/data/jj591620#CascadeDelete

1 个答案:

答案 0 :(得分:5)

自我参考表

SQL Server不允许自引用表进行级联删除。

  

正如您所看到的,SQL Server注意到您的级联操作是   循环,它不允许这种类型的级联。事实并非如此   仅适用于自引用表,也适用于任何链   级联操作具有的表之间的关系   潜在的周期性。

Source

这就是为什么在EF中你无法在自引用实体上设置级联删除。

.WillCascadeOnDelete(true); // Not allowed.

如果依赖实体上的外键可以为空,则Code First会这样做 没有在关系上设置级联删除

是关于EF的default convention,你可以用流畅的api覆盖它。如果您有以下代码,

public int? ParentId { get; set; } // <--- nullable
public Account Parent { get; set; }

EF默认情况下会将级联删除标记为false,即使您没有使用WillCascadeOnDelete(false)进行配置,这实际上意味着数据库中的外键级联删除将设置为ON DELETE NO ACTION

目前EF不支持ON DELETE SET NULL,除非您有自定义查询要删除并重新添加约束,请检查this post

当删除主体时,外键将设置为空。

这已在this post中解释,这意味着只有将孩子加载到上下文中。