简体   繁体   English

识别和删除实体框架子记录

[英]Identifying and Deleting Entity Framework child records

I have the following objects defined in EF; 我在EF中定义了以下对象;

public class ItemA()
{
        public virtual ICollection<ItemB> Items{ get; set; }
}

public class ItemB()
{
        public virtual ICollection<ItemC> Items{ get; set; }
}

In my code, I am doing the following; 在我的代码中,我正在做以下事情;

myItemA.Items.Remove(myItemA.Items.FirstOrDefault(x => (int)x.Type == model.Type));

myItemA.Items.Add(new ItemB());

When the instance of ItemA is populated, it contains a single ItemB and I simply want to replace this with the new instance of ItemB. 当填充ItemA的实例时,它包含单个ItemB,我只想将其替换为ItemB的新实例。 When I get into my Service to update the message, I noticed that simply calling the following code resulted in the new ItemB and the existing ItemB becomes orphaned with the parent ID being null. 当我进入我的服务更新消息时,我注意到只是调用以下代码导致新的ItemB,并且现有的ItemB变为孤立状态,父ID为null。 The links between ItemB and ItemC are intact. ItemB和ItemC之间的链接完好无损。

_dbContext.Entry(entity).State = EntityState.Modified;
_dbContext.SaveChanges();

So, I know that I need to tell EF that the child ItemB is to be deleted and the constraints setup in the model will hopefully cascade delete the child ItemC records and then the orphaned ItemB. 因此,我知道我需要告诉EF要删除子ItemB,并且模型中的约束设置有望级联删除子ItemC记录,然后删除孤立的ItemB。 However, I am struggling to find a way of doing so. 但是,我正在努力寻找一种方法。

I have tried re-getting the Parent ItemA from the context to compare the List and mark them as deleted, but as I am getting the proxy back, both objects are essentially the same and only have the updated ItemB and not the original. 我尝试从上下文中重新获取Parent ItemA以比较List并将它们标记为已删除,但是当我收回代理时,两个对象基本相同,只有更新的ItemB而不是原始的。

var existingItem = GetItem(entity.Id);

or 要么

var existing Items = GetItem(entity.Id).Items.ToList();

So what I need is the original ItemA.Items to be able to tell EF they are to be deleted. 所以我需要的是原始的ItemA.Items能够告诉EF他们将被删除。 Please note that I know how to tell EF that something should be deleted, I am only interested in getting a reference to the entity that should be deleted. 请注意,我知道如何告诉EF应删除某些内容,我只对获取应该删除的实体的引用感兴趣。

EDIT 编辑

Adding this code makes it work and the orphaned ItemB (with child ItemC) are now removed, however, as far as I understand it, this will now be done within 2 transactions. 添加此代码使其工作,孤立的ItemB(带有子ItemC)现在被删除,但据我所知,现在将在2个事务中完成。

    //Update Message
    _dbContext.Entry(entity).State = EntityState.Modified;
    _dbContext.SaveChanges();

    //Remove any orphaned records
    var itemsToRemove = _dbContext.Set<ItemB>().Where(x => x.ItemA == null).ToList();
    _dbContext.Set<ItemB>().RemoveRange(itemsToRemove );
    _dbContext.SaveChanges();

Ideally, looking for a way to do this a single SaveChanges() 理想情况下,寻找一种方法来执行此单个SaveChanges()

Umm.. did i understand something wrong or do you only want to implement a cascade delete like this: 嗯..我明白了什么不对,或者你只是想实现这样的级联删除:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<ItemB>().HasRequired(b => b.Parent).WithMany(a => a.Items).WillCascadeOnDelete();
}

This should also work: 这应该也有效:

public class ItemA()
{
    public virtual ICollection<ItemB> Items{ get; set; }
}

public class ItemB()
{
    [Required] // This set's the constraint
    public virtual ItemA Parent { get; set; }
    public virtual ICollection<ItemC> Items{ get; set; }
}

Did't use the second one, yet, but it should have the identical result. 然而,没有使用第二个,但它应该具有相同的结果。

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

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