我正在尝试通过覆盖 DbContext.SaveChanges()
方法并撤消对实现我的 ISoftDelete
接口(interface)的任何实体的删除,在我的项目中实现软删除功能.
interface ISoftDelete
{
bool IsDeleted { get; set; }
}
在 SaveChanges()
方法中,我为每个处于“已删除”状态并实现 ISoftDelete
的条目调用我的 SoftDelete() 方法。:
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;
}
}
在我遇到一个与其他事物具有一对一关联的实体之前,这将完美运行。此时,将抛出异常并出现此错误:
{"A relationship from the 'ChildParent' AssociationSet is in the 'Deleted' state. Given multiplicity constraints, a corresponding 'Parent' must also in the 'Deleted' state."}
有没有办法获取该实体的所有关联并更改它们的已删除状态?
我已经尝试获取对实际关联实体的引用,但实体的 EntityState
设置为 Unchanged
而不是 Deleted
。
最佳答案
一般情况下,需要先软删除父子关系中的childs。从最顶层的 parent 开始,递归通过 child 。标记访问过的每个项目,以便您可以跟踪它是否已被软删除(在反向引用的情况下)。
如果您有“业务对象”的概念,您可以添加Childs
和Parent
属性以便于导航。否则,您将不得不在具有非平凡子关系的每个 Parent 上“手动编码”。
另请注意,使用一个 LINQ 语句您无法控制实际遍历。
我知道上面的工作似乎很多,但请考虑如何在 EF 中设置一种机制来自动推断所需的关系信息?!你最终会做这样的事情。
关于c# - 使用关联覆盖实体删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12693961/