用关联覆盖实体删除

时间:2012-10-02 16:01:32

标签: c# entity-framework entity-framework-4

我试图通过覆盖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

1 个答案:

答案 0 :(得分:0)

通常,您需要先在父子关系中软删除子项。从最顶层的父母开始,逐步通过孩子。标记所访问的每个项目,以便您可以跟踪它是否已被软删除(如果是反向引用)。

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

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

我知道上面的内容似乎很多,但考虑一下如何在EF中设置一个能够自动推断所需关系信息的机制?!你最终会做这样的事情。