根据Global Query Filters文档,我们不能为一个实体使用多个查询过滤器,我们只能使用一个带有多个条件的过滤器:
当前无法在同一实体上定义多个查询过滤器-仅应用最后一个。但是,您可以使用逻辑AND运算符(在C#中为&&)定义具有多个条件的单个过滤器。
因此,在我正在使用EF Core 3.1的项目中,我试图做到这一点。在查询过滤器中,我尝试为TenantId
和IsDeleted
应用条件:
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
检查继续拥有。