【问题标题】:Entity framework override save changes to soft delete entities实体框架覆盖对软删除实体的保存更改
【发布时间】:2017-07-29 10:27:19
【问题描述】:

我正在尝试覆盖我的数据库上下文中的 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:我看不出这个问题如何与 this 重复

【问题讨论】:

  • 您可以使用反射来查看存在哪些导航属性,并查看它们是否包含外键,谁与您的键匹配,但这需要进行大量更改,但这仍然比记住所有属性要好手动。您可以通过反射查找表的主键,
  • 嗯,是的,这需要进行大量更改,并且会有些混乱。不过我确信有更好的解决方案......
  • Entity Framework soft delete implementation using database interceptor not working 的可能重复项(请检查实现,这可能是您实现此的更好方法,而不是仅挂钩到更改上下文中
  • 我不这样做的原因是我希望能够拥有一个可以清除实体的超级管理员。在更改上下文中,很容易检查身份,如果实体被删除,只需继续执行删除命令。在拦截器中这并不容易
  • 相关问题可能有帮助:stackoverflow.com/q/38998535/492

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


【解决方案1】:

我会在 DBMS 端尝试一些东西,而不是在应用程序端。

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

所以在你的情况下,我要做的是修改外键。假设您有两个表:

人员:(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。

【讨论】:

  • 谢谢。我会考虑这是一种选择。我只是不想弄乱我的迁移文件,因为我使用代码优先方法。
  • 有没有办法从代码优先的方法做到这一点?
  • 我不这么认为——至少不是自动的。您可以使用 EF 创建复合 FK,但不能使用 EF 指定级联更新功能(如级联删除)。一个可能的选择是添加 ALTER 语句以将 FK 修改到您的迁移文件中。
猜你喜欢
  • 2016-07-12
  • 1970-01-01
  • 1970-01-01
  • 2014-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多