C# 实体框架覆盖将更改保存到软删除实体

C# 实体框架覆盖将更改保存到软删除实体,c#,entity-framework,entity-framework-6,C#,Entity Framework,Entity Framework 6,我试图覆盖数据库上下文中的Savechanges,将我的实体标记为SoftDeleted 我有一个ISoftDeletable基,我在实体类中重写它 public interface IsoftDeletable { public bool IsDeleted {get; set;} } 然后在我的背景下 public override int SaveChanges() { foreach (var entry in ChangeTracker.Entries()

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

我有一个ISoftDeletable基,我在实体类中重写它

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;
}
如果我删除一个实体,上面的示例可以正常工作,但它会被软删除,但问题是,如果该实体具有带有级联删除的子集合,则子集合不会被实体框架跟踪,也不会被标记为已删除

一个简单的解决方案是在删除发生之前急切地加载要删除的实体的所有子集合,以便Ef也跟踪子集合中的更改并软删除它们,但这是我想要避免的“黑客行为”。在删除发生之前,很难记住实体之间的所有关系并加载所有内容。而且,如果模型发生变化,则很难保持这种状态

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


编辑1:我看不出这个问题有多复杂,我会在DBMS方面而不是在应用程序方面尝试一些东西

我假设您有MS SQL Server。MS SQL Server以与“级联删除”类似的方式支持“级联更新”。这意味着,如果您有一个主键为PersonID的Person表和一个Car表,其中PersonID外键引用PersonID表中的PersonID,则每当您亲自更改PersonID的值时,Car中相关记录中的外键也会用该值更新

因此,在您的情况下,我要做的是修改外键。假设您有两张桌子:

人物:(人名、姓名、年龄、删除)
汽车:(身份、品牌、型号、人名、删除)


PersonID是当面PK,CarId是车内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。

您可以使用反射查看存在哪些导航属性,并查看它们是否包含与您的密钥匹配的外键,但这需要进行大量更改,但仍比手动记住所有这些属性要好。您可以通过反射查找表的主键,是的,这需要很多更改,而且会有点混乱。我确信有更好的解决方案,但…可能的重复(请检查实现,这可能是一个更好的方法,您可以实现这一点,而不是只挂接到更改上下文)我不这样做的原因是,我希望能够有一个超级管理员谁可以清除实体。在更改上下文中,可以很容易地检查标识,如果删除了实体,只需继续执行delete命令。在拦截器中,这并不容易。相关问题可能会有所帮助:谢谢。我会认为这是一种选择。我只是不想弄乱我的迁移文件,因为我使用代码优先的方法。有没有一种方法可以从代码优先的方法来做到这一点?我不这么认为-至少不是自动的。可以使用EF创建复合FK,但不能使用EF指定级联更新功能(如级联删除)。一个可能的选项是添加ALTER语句,以修改迁移文件中的FK。