使用 EF Core 保存附加实体时如何删除子实体
Posted
技术标签:
【中文标题】使用 EF Core 保存附加实体时如何删除子实体【英文标题】:How to remove child entities when saving attached entity with EF Core 【发布时间】:2018-04-05 18:07:20 【问题描述】:我有一个使用 EF Core 的存储库。在下面的场景中,我首先获取一个实体以及一个相关的子集合。然后,我删除所有子项并添加一个新子项,并更新父实体上的一个属性。
在父节点上保存属性更新后,新的子实体被添加,但所有原始子实体仍在数据库中。
如何让 EF 将已删除的子实体跟踪为已删除?
class Repository
public Parent GetParent(int id)
using (var db = new LocalDbContext())
return db.Parents.Include(item => item.Images).FirstOrDefault(item => item.Id == id);
public void UpdateParent(Parent parent)
using (var db = new LocalDbContext())
var entry = db.Parents.Attach(parent);
entry.State = EntityState.Modified;
db.SaveChanges();
var instance = new LocalDbContext();
var repository = new Repository();
var parent = repository.GetParent(123);
parent.SomeField = 999;
parent.Children.RemoveRange(0, parent.Children.Count);
parent.Children.Add(new Child() SomeOtherField = "qwe" );
repository.UpdateParent(parent);
【问题讨论】:
【参考方案1】:打电话
db.Children.RemoveRange(parent.Children);
应该从数据库中删除子实体。
在存储库中添加方法:
public void RemoveChildren(IEnumerable<Children> children)
using(var db = new LocalDbContext())
db.Children.RemoveRange(children);
db.SaveChanges();
并使用它:
var parent = repository.GetParent(123);
repository.RemoveChildren(parent.Children);
【讨论】:
你会把那行代码放在上面代码的什么地方? 可能需要注意的是,不同之处在于parent.Children.RemoveRange
只削减了关联,即使外键无效。
我可能应该补充说我想在一个事务中更新父级,这样我就不会在不更新父级的情况下删除子级。向我的存储库添加一个新方法并不是我想要的答案。
@MathiasR 另一种选择是为存储库使用单个上下文实例,方法是将其注入构造函数中。
是的。存储库不应使用私有上下文实例,也不应执行 SaveChanges。一个包容性的工作单元应该做到这一点。 (更不用说这个额外的存储库层是一种反模式)。以上是关于使用 EF Core 保存附加实体时如何删除子实体的主要内容,如果未能解决你的问题,请参考以下文章
EF Core 在对现有查询添加查询时附加所有实体 [重复]
Entity Framework Core中更改跟踪工作原理
Entity Framework Core中更改跟踪工作原理