Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю
// Expression<Func<Customer>> - это лямбда-выражение. Expression<Func<Customer, bool>> expression = x => x.Id == 10; // Возвращается null, когда ничего не найдено. var customer = Context.Customers.SingleOrDefault(expression); Assert.Null(customer);}Предыдущий запрос LINQ транслируется в такой код SQL:
SELECT TOP(1) [c].[Id], [c].[TimeStamp], [c].[FirstName], [c].[FullName], [c].[LastName] FROM [Dbo].[Customers] AS [c]WHERE [c].[Id] = 10Глобальные фильтры запросов
Вспомните о наличии для сущности
CarIsDrivablefalsemodelBuilder.Entity<Car>(entity =>{ entity.HasQueryFilter(c => c.IsDrivable); ...});Откройте файл класса
CarTests.csСаrTests.cs[Fact]public void ShouldReturnDrivableCarsWithQueryFilterSet(){ IQueryable<Car> query = Context.Cars; var qs = query.ToQueryString(); var cars = query.ToList(); Assert.NotEmpty(cars); Assert.Equal(9, cars.Count);}Также вспомните, что в процессе инициализации данных были созданы 10 записей об автомобилях,из которых один установлен как неуправляемый. При запуске запроса применяется глобальный фильтр запросов и выполняется следующий код 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)На заметку! Как вскоре будет показано, глобальные фильтры запросов также применяются при загрузке связанных сущностей и при использовании методов
FromSqlRaw()FromSqlInterpolated()Отключение глобальных фильтров запросов
Чтобы отключить глобальные фильтры запросов для сущностей в запросе, добавьте к запросу LINQ вызов метода
IgnoreQueryFilters()Where()CarTests.cs[Fact]public void ShouldGetAllOfTheCars(){ IQueryable<Car> query = Context.Cars.<b>IgnoreQueryFilters()</b>; var qs = query.ToQueryString(); var cars = query.ToList(); Assert.Equal(10, cars.Count);}Как и можно было ожидать, в сгенерированном коде SQL больше нет конструкции
WHERESELECT [i].[Id], [i].[Color], [i].[IsDrivable], [i].[MakeId], [i].[PetName], [i].[TimeStamp] FROM [dbo].[Inventory] AS [i]Фильтры запросов для навигационных свойств
Помимо глобального фильтра запросов для сущности
CarCarNavigationOrdermodelBuilder.Entity<Order>().HasQueryFilter(e => e.CarNavigation!.IsDrivable);Чтобы увидеть его в действии, добавьте в файл класса
OrderTests.cs[Fact]public void ShouldGetAllOrdersExceptFiltered(){ var query = Context.Orders.AsQueryable(); var qs = query.ToQueryString(); var orders = query.ToList(); Assert.NotEmpty(orders); Assert.Equal(4,orders.Count);}Вот сгенерированный код 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)rn) AS [t] ON [o].[CarId] = [t].[Id]WHERE [t].[IsDrivable] = CAST(1 AS bit)Поскольку навигационное свойство
CarNavigationINNER JOINOrderCarIgnoreQueryFilters()