Глобальные фильтры запросов позволяют добавлять конструкцию
where
во все запросы LINQ для определенной сущности. Например, распространенное проектное решение для баз данных предусматривает использование "мягкого" удаления вместо "жесткого". В таблицу добавляется поле, указывающее состояние удаления записи. Если запись "удалена", то значение поля устанавливается в
true
(или
1
), но запись из базы данных не убирается. Прием называется "мягким" удалением. Чтобы отфильтровать записи, повергнувшиеся "мягкому" удалению, от тех, которые обрабатывались
нормальными операциями, каждая конструкция
where
обязана проверять значение поля с состоянием удаления записи. Включение такого фильтра в каждый запрос может занять много времени, да и не забыть о нем довольно проблематично.
Инфраструктура EF Core позволяет добавлять к сущности глобальный фильтр запросов, который затем применяется к каждому запросу, вовлекающему эту сущность. Для описанного выше примера с "мягким" удалением вы устанавливаете фильтр на сущностном классе, чтобы исключить записи, повергнувшиеся "мягкому" удалению. К любым создаваемым EF Core запросам, затрагивающим сущности с глобальными фильтрами запросов, будут применяться их фильтры. Вам больше не придется помнить о необходимости включения конструкции
where
в каждый запрос.
Придерживаясь в книге темы автомобилей, предположим, что все записи
Car
, которые не являются управляемыми, должны отфильтровываться из нормальных запросов. Вот как можно добавить глобальный фильтр запросов с использованием Fluent API:
удаляет фильтр запросов для всех сущностей в запросе LINQ, в том числе и тех, которые задействованы в вызовах
Include
или
Thenlnclude
.
Глобальные фильтры запросов на навигационных свойствах
Глобальные фильтры запросов можно также устанавливать на навигационных свойствах. Пусть вам необходимо отфильтровать любые заказы, которые содержат экземпляр
Car
, представляющий неуправляемый автомобиль. Фильтр создается на навигационном свойстве
При выполнении стандартного запроса LINQ любые заказы, содержащие неуправляемый автомобиль, будут исключаться из результата. Ниже показан оператор LINQ и генерированный оператор SQL:
Здесь уместно предостеречь: исполняющая среда EF Core не обнаруживает циклические глобальные фильтры запросов, поэтому при добавлении фильтров запросов к навигационным свойствам соблюдайте осторожность.
Явная загрузка с глобальными фильтрами запросов
Глобальные фильтры запросов действуют и при явной загрузке связанных данных. Например, если вы хотите загрузить записи
Car
для
Make
, то фильтр
IsDrivable
предотвратит загрузку в память записей, представляющих неуправляемые автомобили. В качестве примера взгляните на следующий фрагмент кода:
var make = Context.Makes.First(x => x.Id == makeId);