Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю
Придерживаясь в книге темы автомобилей, предположим, что все записи
CarmodelBuilder.Entity<Car>(entity =>{<b> entity.HasQueryFilter(c => c.IsDrivable == true);</b> entity.Property(p => p.IsDrivable).HasField("_isDrivable"). HasDefaultValue(true);});Благодаря такому глобальному фильтру запросов запросы, вовлекающие сущность
Carvar cars = Context.Cars.ToList();приводит к выполнению показанного ниже оператора SQL:
SELECT [i].[Id], [i].[Color], [i].[IsDrivable], [i].[MakeId], [i].[PetName], [i].[TimeStamp]FROM [Dbo].[Inventory] AS [i]WHERE [i].[IsDrivable] = CAST(1 AS bit)Если вам нужно просмотреть отфильтрованные записи, тогда добавьте в запрос LINQ вызов
IgnoreQueryFilters()var cars = Context.Cars.IgnoreQueryFilters().ToList();инициирует выполнение следующего оператора SQL:
SELECT [i].[Id], [i].[Color], [i].[IsDrivable], [i].[MakeId], [i].[PetName], [i].[TimeStamp]FROM [Dbo].[Inventory] AS [i]Важно отметить, что вызов
IgnoreQueryFilters()Include()Thenlnclude()Глобальные фильтры запросов на навигационных свойствах
Глобальные фильтры запросов можно также устанавливать на навигационных свойствах. Пусть вам необходимо отфильтровать любые заказы, которые содержат экземпляр
CarCarNavigationOrdermodelBuilder.Entity<Order>().HasQueryFilter(e => e.CarNavigation.IsDrivable);При выполнении стандартного запроса LINQ любые заказы, содержащие неуправляемый автомобиль, будут исключаться из результата. Ниже показан оператор LINQ и генерированный оператор SQL:
// Код C#var orders = Context.Orders.ToList();/* Сгенерированный запрос SQL */SELECT [o].[Id], [o].[CarId], [o].[CustomerId], [o].[TimeStamp]FROM [Dbo].[Orders] AS [o]INNER JOIN (SELECT [i].[Id], [i].[IsDrivable] FROM [Dbo].[Inventory] AS [i] WHERE [i].[IsDrivable] = CAST(1 AS bit)) AS [t] ON [o].[CarId] = [t].[Id]WHERE [t].[IsDrivable] = CAST(1 AS bit)Для удаления фильтра запросов используйте вызов
IgnoreQueryFilters()// Код C#var orders = Context.Orders.IgnoreQueryFilters().ToList();/* Сгенерированный запрос SQL */SELECT [o].[Id], [o].[CarId], [o].[CustomerId], [o].[TimeStamp]FROM [Dbo].[Orders] AS [o]Здесь уместно предостеречь: исполняющая среда EF Core не обнаруживает циклические глобальные фильтры запросов, поэтому при добавлении фильтров запросов к навигационным свойствам соблюдайте осторожность.
Явная загрузка с глобальными фильтрами запросов
Глобальные фильтры запросов действуют и при явной загрузке связанных данных. Например, если вы хотите загрузить записи
CarMakeIsDrivablevar make = Context.Makes.First(x => x.Id == makeId);Context.Entry(make).Collection(c=>c.Cars).Load();К настоящему моменту не должен вызывать удивление тот факт, что сгенерированный оператор SQL включает фильтр для неуправляемых автомобилей:
SELECT [i].[Id], [i].[Color], [i].[IsDrivable], [i].[MakeId], [i].[PetName], [i].[TimeStamp]FROM [Dbo].[Inventory] AS [i]WHERE ([i].[IsDrivable] = CAST(1 AS bit)) AND ([i].[MakeId] = 1С игнорированием фильтров запросов при явной загрузке данных связана небольшая загвоздка. Возвращаемым типом метода
Collection()CollectionEntry<Make,Car>IQueryable<T>IgnoreQueryFilters()Query()IQueryable<Car>var make = Context.Makes.First(x => x.Id == makeId);Context.Entry(make).Collection(c=>c.Cars).Query().IgnoreQueryFilters().Load();