删除独立关联的主体和从属项(一对多)

本文关键字:一对多 独立 关联 主体 删除 | 更新日期: 2023-09-27 18:05:58

使用实体框架6和设计器,我们所有的实体都有一个独立的关联。因此,在我们模型的属性中没有定义外键。

具有以下具有一对多关系的实体:

public class Parent
{
    public Guid Id { get; set; }
    public virtual ICollection<Child> Children { get; set; }
}
public class Child
{
    public Guid Id { get; set; }
    public virtual Parent Parent { get; set; }
}

映射到以下SQL表:

CREATE TABLE Parent (
    Id uniqueidentifier NOT NULL,
    CONSTRAINT PK_Parent PRIMARY KEY CLUSTERED (Id)
)
CREATE TABLE Child (
    Id uniqueidentifier NOT NULL,
    FkParent uniqueidentifier NOT NULL,
    CONSTRAINT PK_Child PRIMARY KEY CLUSTERED (Id)
)
ALTER TABLE Child WITH CHECK
ADD CONSTRAINT FK_Child_Parent FOREIGN KEY(FkParent) REFERENCES Parent ([Id])
ALTER TABLE Child CHECK CONSTRAINT FK_Child_Parent

正如你所看到的,我们没有使用CASCADE ON DELETE,因为我的团队反对使用它

因此,问题是,在只给定父母的Id的情况下,删除父母及其从属子女的正确方法是什么
使用delete,我的意思是在调用.SaveChanges()之后,应该删除两个表中的SQL记录(生成DELETESQL语句(。

删除独立关联的主体和从属项(一对多)

所以我找到如何实现这一点的唯一方法是显式地将子项加载到内存中,并在实际删除父项之前逐个删除它们。

using (var context = new MyDbContext())
{
    var parent = context.Parents.Find(parentId);
    //or use LINQ if you prefer:
    var alternative = context.Parents.Single(p => p.Id == parentId)
    foreach(var child in parent.Children.ToList())
    {
        context.Children.Remove(child);
    }
    context.Parents.Remove(parent);
    context.SaveChanges();
}

请注意Children上的.ToList()(或.ToArray(),如果您愿意(,这是重要,如本答案中所述。

就性能而言,这并不理想,因为您必须查询数据库中的每个子记录,并将其加载到内存中(我想对于小型应用程序来说,这并不重要(。但如果不使用CASCADE ON DELETE,我找不到更好的方法,尽管我不确定这是否真的会优于这种情况。