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

本文关键字:记录 框架 实体 删除 识别 | 更新日期: 2023-09-27 18:02:45

在EF中定义了以下对象;

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

在我的代码中,我做了以下操作;

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

当填充ItemA实例时,它包含一个ItemB,我只是想用ItemB的新实例替换它。当我进入Service更新消息时,我注意到只需调用以下代码就会导致新的ItemB和现有的ItemB成为孤儿,父ID为空。ItemB和ItemC之间的链接是完整的。

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

因此,我知道我需要告诉EF要删除子ItemB,并且模型中设置的约束将有希望级联删除子ItemC记录,然后是孤立的ItemB。然而,我正在努力寻找这样做的方法。

我已经尝试从上下文中重新获得父ItemA来比较列表并将它们标记为已删除,但是当我获得代理返回时,两个对象本质上是相同的,只有更新的ItemB而不是原始的。

var existingItem = GetItem(entity.Id);

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

所以我需要的是原始的ItemA。能够告诉EF它们要被删除的项。请注意,我知道如何告诉EF某些东西应该被删除,我只对获得应该被删除的实体的引用感兴趣。

编辑

添加这段代码使其工作,孤立的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();

理想情况下,寻找一种方法来做到这一点,一个单一的SaveChanges()

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

嗯…我理解错了吗?还是你只想实现这样的级联删除:

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

也可以:

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

没有使用第二个,但它应该有相同的结果