我试图在“数据库上下文”中覆盖Savechanges,以将我的实体标记为SoftDeleted。

我有一个ISoftDeletable基础,我在Entity类中对其进行了覆盖

public interface IsoftDeletable
{
    public bool IsDeleted {get; set;}
}


然后在我的上下文中

public override int SaveChanges()
{
    foreach (var entry in ChangeTracker.Entries()
              .Where(p => p.State == EntityState.Deleted))
        SoftDelete(entry);

    return base.SaveChanges();
}

private void SoftDelete(DbEntityEntry entry)
{
   var entity = entry.Entity as ISoftDeltable;
   entity.IsDeleted = true;
   entry.State = EntityState.Modified;
}


上面的示例可以正常工作,如果我删除一个实体,它会被软删除,但问题是,如果该实体具有带有Cascade删除功能的子集合,则该子框架不会被实体框架跟踪,也不会标记为已删除。

一个简单的解决方案是在删除发生之前急切地加载要删除的实体的所有子级集合,因此Ef也会跟踪子级中的更改并对其进行软删除,但这是我要避免的“ hack” 。很难记住实体之间的所有关系,并在删除发生之前就急于加载所有内容。此外,如果模型发生更改,将很难维持这一点。

有没有更好的方法来实现这种功能?

编辑1:我看不到这个问题怎么可能复制this

最佳答案

我会尝试在DBMS方面而不是在应用程序方面进行尝试。

我假设您有MS SQL Server。 MS SQL Server支持“级联更新”的方式与“级联删除”的方式类似。这意味着,如果您有一个具有主键PersonID的Person表和一个Car表,并且其中有一个PersonID外键引用该Person表中的PersonID,则每当您更改PersonID中Person的值时,相关记录中的外键汽车也将使用此值进行更新。

因此,在您的情况下,我将要做的就是修改外键。假设您有两个表格:

人员:(PersonId,姓名,年龄,IsDeleted)汽车:(CarId,品牌,型号,PersonId,IsDeleted)

PersonID是Person中的PK,而CarId是Car中的PK。而不是使Car.PersonId成为引用Person.PersonId的FK,而是创建一个复合外键:(Car.PersonId,Car.IsDeleted)=>(Person.PersonId,Person.IsDeleted)然后指定“更新级联”复合FK的选项。这样,每当您更改Person.PersonId(永远不会)或Person.IsDeleted时,新值将被级联更新为相应的Car.PersonId(由于Person.PersonId不会更改,因此不会级联更新),并且Car.IsDeleted。

关于c# - Entity Framework 将保存更改覆盖到软删除实体,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42678359/

10-11 15:16