我试图通过覆盖DbContext.SaveChanges()
方法并撤消删除任何实现我的ISoftDelete
接口的实体来在我的项目中实现软删除功能。
interface ISoftDelete
{
bool IsDeleted { get; set; }
}
在SaveChanges()
方法中,我为每个处于“已删除”状态的条目调用我的SoftDelete()方法并实现ISoftDelete
。:
var entries = this.ChangeTracker.Entries().Where(x => (x.State == EntityState.Deleted) && x.Entity is ISoftDelete)
.ToList();
entries.ForEach(SoftDelete);
我的SoftDelete()
方法如下:
private void SoftDelete(DbEntityEntry entry)
{
if (entry.State == EntityState.Deleted && entry.Entity is ISoftDelete)
{
entry.Reload();
var entity = (ISoftDelete)entry.Entity;
entity.IsDeleted = true;
entry.State = EntityState.Modified;
}
}
这将完美地运行,直到我遇到一个与其他东西有一对一关联的实体。此时,抛出此错误会引发异常:
{“来自'ChildParent'AssociationSet的关系在 '已删除'状态。给定多重约束,相应的 “父母”也必须处于“已删除”状态。“}
是否有办法获取该实体的所有关联并更改它们的已删除状态?
我已尝试获取对实际关联实体的引用,但实体的EntityState
设置为Unchanged
而不是Deleted
。
答案 0 :(得分:0)
通常,您需要先在父子关系中软删除子项。从最顶层的父母开始,逐步通过孩子。标记所访问的每个项目,以便您可以跟踪它是否已被软删除(如果是反向引用)。
如果您有“业务对象”概念,则可以添加Childs
和Parent
属性以方便导航。否则你将不得不在每个父母身上“手动编码”这个与非平凡的子关系。
另请注意,使用一个LINQ语句,您无法控制实际的遍历。
我知道上面的内容似乎很多,但考虑一下如何在EF中设置一个能够自动推断所需关系信息的机制?!你最终会做这样的事情。