首页 > 解决方案 > 如何使用存储库忽略包含实体的 softDelete 查询过滤器?

问题描述

我为使用 EfCore5 的项目创建了一个 DataLayer,我将 DbContext 配置为处理 softDelete 记录:

//DbContext    
modelBuilder.Entity<EntityName>().HasQueryFilter(p => !p.Deleted);

在我的存储库中:

   // Repository Interface
    public interface IRepository<T,TKey> where T : class
    {
        ICollection<T> FindAll(Expression<Func<T, bool>> filter = null, Func<IQueryable<T>, IIncludableQueryable<T, object>> include = null, bool hideDeleted = true);
    }

   // Repository
   public class Repository<TEntity, TKey> : IRepository<TEntity, TKey> where TEntity : class, IEntity<TKey>
    {
        public ICollection<TEntity> FindAll(Expression<Func<TEntity, bool>> filter = null, Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> include = null, bool hideDeleted = true)
        {
            using var db = new TEGVContext();
            IQueryable<TEntity> query = db.Set<TEntity>();
            if (!hideDeleted)
                query = query.IgnoreQueryFilters();

            if (include != null)
                query = hideDeleted ? include(query) : include(query).IgnoreQueryFilters();

            return filter == null
                ? query.ToList()
                : query.Where(filter).ToList();
        }
    }

在控制器中:

 var model = _Repo.FindById(id, include: a => a
                        .Include(x => x.Entity2).ThenInclude(l => l.Entity2_1)
                        .Include(x => x.Entity3).ThenInclude(l => l.Entity3_1), false);

在我的代码中,IgnoreQueryFilters 与主实体一起使用,但不适用于 Include 和 ThenInclude,include 中的被调用实体仍然应用 queryFilter。

如何使我的代码能够忽略所选包含的查询过滤器?有没有更好的方法来做到这一点?

标签: c#entity-frameworkasp.net-core

解决方案


IgnoreQueryFilters是影响查询中所有实体的查询级别选项。没有选项可以仅针对查询中的某些实体关闭查询过滤器。

你为什么要写

var model = _Repo.FindById(id, include: a => a
                        .Include(x => x.Entity2).ThenInclude(l => l.Entity2_1)
                        .Include(x => x.Entity3).ThenInclude(l => l.Entity3_1), false);

而不是更直接

var model = _Repo.FindById(id)
                 .IgnoreQueryFilters()
                 .Include(x => x.Entity2).ThenInclude(l => l.Entity2_1)
                 .Include(x => x.Entity3).ThenInclude(l => l.Entity3_1)
                 .ToList();

你会通过让你的存储库包装器返回一个 IQueryable 来获得?或者

var model = db.Entity1
              .IgnoreQueryFilters()
              .Where(e => e.Id == id)
              .Include(x => x.Entity2).ThenInclude(l => l.Entity2_1)
              .Include(x => x.Entity3).ThenInclude(l => l.Entity3_1)
              .ToList();

您是通过完全删除自定义存储库包装器来获得的吗?


推荐阅读