在没有实际删除记录的情况下保持参照完整性

时间:2016-12-28 19:53:38

标签: c# sql-server entity-framework

我没有从数据库中删除条目,而是计划在每个表中使用类似isActive的布尔列并管理其true/false状态。

通常,当您从数据库中删除记录时,

  1. 维护参照完整性,这意味着在删除其依赖项之前无法删除它。
  2. 当您查询已删除的记录时,它将返回null
  3. 如何使用Entity Framework以自动方式获得相同的结果?因为手动检查每个查询中的每个实体的isActive字段似乎太多工作,这将是容易出错的。将依赖关系标记为isActive=false也是如此。

    修改

    我的目的不仅限于时间点查询。让我举个例子。 UserA发布了一张照片,UserB写了一条评论。然后UserB想要删除他的帐户。但该评论的海报FK指向UserB。因此,我不是要删除UserB,而是要停用其帐户,但保留记录以便不破坏依赖关系。 我想将此逻辑扩展到数据库中的每个表。这是错的吗?

3 个答案:

答案 0 :(得分:1)

作为对这个问题的侧面回答,不是直接查询所有表,为什么不使用Views然后查询视图呢?您可以在视图中放置一个过滤器,仅显示" IsActive = true"记录,这样您就不必担心在每个查询中手动包含它(您提到的内容很容易出错)。

答案 1 :(得分:0)

  

因为手动检查每个查询中的每个实体的isActive字段似乎太多工作,这将是容易出错的

容易出错。但您可能并不总是只想要活动记录(管理页面?)。您可能也不想软删除所有记录,因为并非一切都有意义(根据我的经验)。您可以使用表达式来帮助您为某些方法/存储库提供/连接它们并构建动态查询。

Expression<Func<MyModel, bool>> IsActive = x => x.IsActive;
  

将依赖关系标记为isActive = false

也是如此

基本存储库可以处理所有存储库的删除,这会将状态设置为false(BaseModel将具有IsActive属性)。

        public int Delete<TEntity>(long id) where TEntity : BaseModel
        {
           using (var context = GetContext())
           {
              var dbEntity = context.Set<TEntity>().Find(id);
              dbEntity.IsActive = false;
              return context.SaveChanges();
           }
        }

答案 2 :(得分:0)

有一个名为EF Filters的OSS工具可以实现您的目标:https://github.com/jbogard/EntityFramework.Filters

它允许您设置全局过滤器,如IsActive字段,并且肯定适用于查询。