如何在EF Core中制作条件查询过滤器?

时间:2020-04-28 22:34:08

标签: c# entity-framework-core ef-core-3.1

根据Global Query Filters文档,我们不能为一个实体使用多个查询过滤器,我们只能使用一个带有多个条件的过滤器:

当前无法在同一实体上定义多个查询过滤器-仅应用最后一个。但是,您可以使用逻辑AND运算符(在C#中为&&)定义具有多个条件的单个过滤器。

因此,在我正在使用EF Core 3.1的项目中,我试图做到这一点。在查询过滤器中,我尝试为TenantIdIsDeleted应用条件:

internal Expression<Func<TEntity, bool>> QueryFilters<TEntity>()
    where TEntity : class {
    return _ => (TenantId.HasValue
                 && _ is ITenantableEntity
                 && ((ITenantableEntity)_).TenantId == new TenantId(TenantId.Value)
                    || true)
                && (_ is IDeletableEntity
                    && !((IDeletableEntity)_).IsDeleted
                    || true);
}

TenantId被定义为DbContext上的一个属性:

internal int? TenantId => _identity.TenantId;

我遇到的问题是,在某些情况下,例如Hangfire后台作业,TenantId将始终为null。我以为在上述情况下我应该注意这一点,但是当我尝试一下时,生成了以下查询参数:

queryContext.AddParameter(
    name: "__ef_filter__HasValue_0",
    value: (object)Invoke(queryContext => Convert(Convert(queryContext.Context, DbContext).TenantId.HasValue, Object), queryContext)
);
queryContext.AddParameter(
    name: "__ef_filter__p_1",
    value: (object)Invoke(queryContext => Convert(Convert(new TenantId(Convert(queryContext.Context, DbContext).TenantId.Value), Nullable`1), Object), queryContext)
);

由于这些参数的缘故,查询只是由于NRE而崩溃。是否有更好或更合适的方法在查询过滤器中构建表达式,以便如果TenantId确实有一个值,则生成参数,否则就没有嵌套条件了?< / p>

要使后台作业中的查询成功,我必须使用IgnoreQueryFilters(),它可以修复TenantId检查,但是现在也忽略了我想执行的IsDeleted检查继续拥有。

0 个答案:

没有答案