简体   繁体   English

EF4 代码优先 - 从数据库中删除父级时删除所有子级?

[英]EF4 Code first - delete all children when deleting parent from db?

I have a class that gets arranged into a hierarchy, such as this:我有一个 class 排列成一个层次结构,例如:

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

So, I have an update method that lets a user upload an updated set of children.所以,我有一个更新方法,可以让用户上传一组更新的孩子。

I didnt realize at first but deleting my container TestContainer doesnt delete the items.起初我没有意识到,但删除我的容器 TestContainer 并不会删除这些项目。

Ok, No problem right?好的,没问题吧?

I inserted the following functions (which is probably very ugly but I am still in the prototyping phase here)我插入了以下函数(这可能非常难看,但我仍处于原型设计阶段)

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

The problem here is that this either crashes my test server, or when I remove the recursive bit (and only remove parents -- testing out what is going wrong at this point), I get the following error这里的问题是,这要么使我的测试服务器崩溃,要么当我删除递归位(并且只删除父母——测试此时出了什么问题)时,我收到以下错误

"An error occurred while saving entities that do not expose foreign key properties for their relationships. The EntityEntries property will return null because a single entity cannot be identified as the source of the exception." “保存不为其关系公开外键属性的实体时发生错误。EntityEntries 属性将返回 null,因为无法将单个实体标识为异常源。”

How can I best cascade delete an Item and all of its Children, so that I do not have orphans in the database?我怎样才能最好地级联删除一个项目及其所有子项,以便我在数据库中没有孤儿? (As I do now) (就像我现在做的那样)

Instead of deleting an entity and its decedents using EF you can enable Cascade delete on the foreign key on your database.您可以在数据库的外键上启用Cascade delete ,而不是使用 EF 删除实体及其后代。 It is much more efficient than generating multiple delete statements.它比生成多个删除语句要高效得多。

Edit编辑

You need to add WillCascadeOnDelete() when you configure the model配置 model 时需要添加WillCascadeOnDelete()

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM