Согласно документации 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;
Проблема, с которой я сталкиваюсь, заключается в том, что в некоторых сценариях ios, таких как фоновые задания Hangfire, TenantId
всегда будет нулевым. Я думал, что защищаю это в вышеупомянутом условии, но когда я попробовал это, были сгенерированы следующие параметры запроса:
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
действительно имел значение, генерировался параметр, а не иначе, как у меня есть вложенное условное выражение?
Чтобы успешно выполнить запрос в фоновом задании, я должен использовать IgnoreQueryFilters()
, который исправляет проверку TenantId
, но теперь также игнорирует проверку IsDeleted
, которую я хотел бы продолжить иметь.