EF4 Code first - 删除父级时删除所有子级?

3

我有一个类,会被安排成层次结构,例如:

class TestContainer
{
... bla bla bla...
  public Virtual Item Items {get;set;}
}
Class Item
{
[Key]
public int ID {get;set;}
public string PropA {get;set;}
public string PropB {get;set;}



[InverseProperty("Parent")]
public virtual ICollection<Item> Children { get; set; }

[InverseProperty("Contents")]
public virtual Item Parent { get; set; }
}

我有一个更新方法,允许用户上传更新后的子项集合。

起初我没有意识到删除容器TestContainer并不会删除其中的项目。

没关系,对吧?

我添加了以下函数(可能很丑陋,但我仍处于原型阶段):

   private void DeleteItems(TestContainer existingContainer)
        {

            //setup a flat list for deletion
            List<Item> trashCan = new List<Item>();
            //delete the old CI's from the database
            BuildDeletionList(existingContainer.Items, ref trashCan);

            foreach (Item item in trashCan)
            {
                context.Items.Remove(item);
            }
        }


        private void BuildDeletionList(ICollection<Item> items, ref List<Item> trashCan)
        {
            if (items != null)
            {
                foreach (Item item in items)
                {

                    BuildDeletionList(item, ref trashCan);
                }
            }

        }

        private void BuildDeletionList(Item item, ref List<Item> trashCan)
        {

            if (Item.Children != null)
            {
                foreach (Item child in Item.Children)
                {
                    BuildDeletionList(item, ref trashCan);
                }
            }
        item.Children.clear();
            trashCan.Add(item);
        }

这里的问题在于,这要么会使我的测试服务器崩溃,要么当我删除递归部分(只删除父项--此时测试一下出了什么问题),我会得到以下错误:
“保存不公开其关系的外键属性的实体时发生错误。 EntityEntries属性将返回null,因为无法将单个实体标识为异常源。”
我该如何最好地级联删除一个项目及其所有子项,以便数据库中没有孤儿?(像现在这样)
1个回答

8

如果您想使用EF删除实体及其子级,可以在数据库上启用外键的级联删除功能。这比生成多个删除语句更有效率。

编辑

在配置模型时需要添加WillCascadeOnDelete()

        modelBuilder.Entity<Item>().HasMany(i => i.Children)
            .WithOptional(i => i.Parent)
            .HasForeignKey(i => i.ParentId)
            .WillCascadeOnDelete();

无论如何,添加适当的[ForeignKey]标签等使我的原始模型工作正常,而明显导致开发服务器崩溃的是在删除每个额外的垃圾桶项目之前未清除内容。我将使用级联,感谢您! - Yablargo
额...你怎么启用级联删除?它可以通过注释实现还是只能使用流畅的API? - Yablargo
1
看起来不错,但遗憾的是我认为它不能在同一张表上运行。好的一面是,当你有多张表的父子关系时,这正是你需要做的。我会将此标记为答案,希望能够满足大多数人的需求。 - Yablargo
@Yablargo 是的,你说得对。你需要删除外键,并在你的DatabaseInitializer中手动创建它,并使用级联删除 - Eranga

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接