C# 如何将实体框架设置为使用可选外键在删除时级联?

C# 如何将实体框架设置为使用可选外键在删除时级联?,c#,entity-framework,ef-code-first,C#,Entity Framework,Ef Code First,我正在尝试将实体框架设置为使用可选外键在删除时级联。我首先使用代码,我的模型如下所示: public class Node { [Key] public int ID { get; set; } [ForeignKey("Parent")] public int? ParentID { get; set; } public virtual Node Parent { get; set; } } 我看到很多解决方案建议“只需要外键”,但这对我不起作用,因

我正在尝试将实体框架设置为使用可选外键在删除时级联。我首先使用代码,我的模型如下所示:

public class Node
{
    [Key]
    public int ID { get; set; }

    [ForeignKey("Parent")]
    public int? ParentID { get; set; }
    public virtual Node Parent { get; set; }
}
我看到很多解决方案建议“只需要外键”,但这对我不起作用,因为父节点可能为null


是否有一种解决方案不涉及在父节点之前手动删除子节点?

这就是您要寻找的吗

从上面看,它可能是(但我没有尝试过):

模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
modelBuilder.Entity()
.has可选(a=>a.Parent)
.WithOptionalDependent()
.WillCascadeOnDelete(真);
}

在这里,MSSQL似乎是罪魁祸首。因为我的表是自引用的,所以不可能将cascadeondelete设置为true

相反,我最终做的是手动递归地标记每个子项以进行删除,然后调用SaveChanges()并让EntityFramework对其余子项进行排序

下面是一个简单的代码示例来说明:

void Delete(bool recursive = false)
{
    if(recursive)
        RecursiveDelete();

    if(this.Parent != null)
        this.Parent.Children.Remove(this);

    using(var db = new MyContext())
    {
        db.SaveChanges();
    }
}
void RecursiveDelete()
{
    foreach(var child in Children.ToArray())
    {
        child.RecursiveDelete();
        Children.Remove(child);
    }

    using(var db = new MyContext())
    {
        db.Nodes.Attach(this);
        db.Entry(this).State = EntityState.Deleted();
    }
}

不幸的是,这对我不起作用。我定义的关系是自引用的,显然MSSQL不支持自引用外键的级联。否则,这将正常工作。谢谢工作正常,但需要用OptionalDependent替换为WithMany(a=>a.Childs)
void Delete(bool recursive = false)
{
    if(recursive)
        RecursiveDelete();

    if(this.Parent != null)
        this.Parent.Children.Remove(this);

    using(var db = new MyContext())
    {
        db.SaveChanges();
    }
}
void RecursiveDelete()
{
    foreach(var child in Children.ToArray())
    {
        child.RecursiveDelete();
        Children.Remove(child);
    }

    using(var db = new MyContext())
    {
        db.Nodes.Attach(this);
        db.Entry(this).State = EntityState.Deleted();
    }
}