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();
}
}