识别和删除实体框架子记录
本文关键字:记录 框架 实体 删除 识别 | 更新日期: 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; }
}
没有使用第二个,但它应该有相同的结果