E.F.6,DB first,soft delete - 计算列

时间:2015-12-18 14:22:12

标签: c# entity-framework-6 edmx ef-database-first soft-delete

我想在使用E.F.6和数据库优先(.edmx)方法的应用程序上实现软删除功能。 以下链接提示和技巧: link1link2我成功完成了以下工作:

  • 在表
  • 上添加了 IsDeleted
  • 在表格中添加了计算列 IsDeletedMapping ,其值与IsDeleted相同
  • 添加了ISoftDelete接口,该接口将在表实体上实现

然后我添加了代码来处理我的SqlRepository Delete方法中对实体的删除操作。

// if has ISoftDelete interface perform soft delete.
if (typeof (ISoftDelete).IsAssignableFrom(typeof (T)))
{
     entry.State = EntityState.Modified;
     var tempEntry = entry.Entity as ISoftDelete;
     tempEntry.IsDeleted = true;
}
// else, mark entity state as Deleted
else
{
     entry.State = EntityState.Deleted;
}

这意味着实现ISoftDelete接口的实体将不会在DB中删除,只需使用IsDeleted = true进行更新。 IsDeletedMapping也将设置为true,因为它是从IsDeleted计算的。

我现在遇到的问题是如何在EF查询中过滤IsDeleted = false。

我尝试的是在IsDeletedMapping上映射条件,因为这意味着EF会自动为我们过滤这个。

Condition mapping of IsDeletedMapping

但这就是问题所在。 IsDeletedMapping将 StoreGeneratedPattern 属性设置为已计算,因此出现错误:

  

错误2016:无法为列成员'IsDeletedMapping'指定条件,因为它标记为'Computed'或'Identity'StoreGeneratedPattern。

所以问题是:在计算列上设置条件映射是否有任何解决方法? 另外,如果你有更好的方法来实现软删除,我会更乐意尝试它。请记住,实现必须自动过滤软删除的记录。

感谢您的回答!

1 个答案:

答案 0 :(得分:0)

我认为您的实施过于复杂。这就是我们所做的:

  1. 将IsDeleted(bool,not null)列添加到表
  2. 将实体的Delete函数映射到实际设置IsDeleted = 0的存储过程,而不是真正的删除。这将强制您映射插入和更新功能,但我们仍然首选程序。
  3. 在edmx
  4. 中按IsDeleted = 0过滤实体

    现在,所有实体都会被IsDeleted = 0自动过滤,并且存储库中的Delete方法可以进行真正的删除,从而隐藏了记录未真正从数据库中删除的事实。因此,如果您想要进行真正的删除操作,或者只对某些实体进行软删除操作,那么您的代码就不会意识到这一点。

    不要忘记,一旦表字段是实体过滤器,它就不能映射到实体属性。您的代码在实体类中没有IsDeleted属性。