用关联覆盖实体删除

Jon*_*han 8 c# entity-framework entity-framework-4

我试图通过覆盖DbContext.SaveChanges()方法并撤消删除任何实现我的ISoftDelete接口的实体来在我的项目中实现软删除功能.

interface ISoftDelete
{
  bool IsDeleted { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

SaveChanges()方法中,我为每个处于"已删除"状态并实现的条目调用我的SoftDelete()方法ISoftDelete:

var entries = this.ChangeTracker.Entries().Where(x => (x.State == EntityState.Deleted) && x.Entity is ISoftDelete)
                    .ToList();
                entries.ForEach(SoftDelete);
Run Code Online (Sandbox Code Playgroud)

我的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;
    }
}
Run Code Online (Sandbox Code Playgroud)

这将完美地工作,直到我遇到一个与其他东西有一对一关联的实体.此时,抛出此错误的异常:

{"来自'ChildParent'AssocSet的关系处于'已删除'状态.给定多重约束,相应的'父'也必须处于'已删除'状态."}

有没有办法获得该实体的所有关联并更改它们的已删除状态?

我已经尝试获取对实际关联实体的引用,但实体EntityState设置为Unchanged而不是Deleted.

mho*_*off 0

一般来说,您需要先软删除父子关系中的子项。从最顶层的父级开始,然后递归到子级。标记访问过的每个项目,以便您可以跟踪它是否已被软删除(以防反向引用)。

如果您有“业务对象”概念,则可以添加ChildsParent属性以便于导航。否则,您将不得不在每个具有非平凡子关系的父级上“手动编码”。

另请注意,使用一个 LINQ 语句您无法控制实际的遍历。

我知道上面的工作量似乎很大,但考虑一下如何在 EF 中设置一种机制来自动推断所需的关系信息?!你最终会做这样的事情。