Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю
На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн Троелсен Эндрю, "Язык программирования C#9 и платформа .NET5" бесплатно, без регистрации.
Энергичная загрузка связанных данных
В предыдущей главе объяснялось, что сущности, которые связаны через навигационные свойства, могут создаваться в одном запросе с применением энергичной загрузки. Метод
Include()ThenInclude()Include()/ThenInclude()Поместите в файл класса
CarTests.csInclude()[Fact]public void ShouldGetAllOfTheCarsWithMakes(){ IIncludableQueryable<Car, Make?> query = Context.Cars.<b>Include(c => c.MakeNavigation)</b>; var queryString = query.ToQueryString(); var cars = query.ToList(); Assert.Equal(9, cars.Count);}Тест добавляет к результатам свойство
MakeNavigationSELECT [i].[Id], [i].[Color], [i].[IsDrivable], [i].[MakeId], [i].[PetName], [i].[TimeStamp], [m].[Id], [m].[Name], [m].[TimeStamp]FROM [dbo].[Inventory] AS [i]INNER JOIN [dbo].[Makes] AS [m] ON [i].[MakeId] = [m].[Id]WHERE [i].[IsDrivable] = CAST(1 AS bit)Во втором тесте используется два набора связанных данных. Первый — это получение информации
MakeOrderCustomerCarOrder[Fact]public void ShouldGetCarsOnOrderWithRelatedProperties(){ IIncludableQueryable<Car, Customer?> query = Context.Cars<b> .Where(c => c.Orders.Any())</b><b> .Include(c => c.MakeNavigation)</b><b> .Include(c => c.Orders).ThenInclude(o => o.CustomerNavigation);</b> var queryString = query.ToQueryString(); var cars = query.ToList(); Assert.Equal(4, cars.Count); cars.ForEach(c => { Assert.NotNull(c.MakeNavigation); Assert.NotNull(c.Orders.ToList()[0].CustomerNavigation); });}Вот сгенерированный запрос:
SELECT [i].[Id], [i].[Color], [i].[IsDrivable], [i].[MakeId], [i].[PetName], [i].[TimeStamp], [m].[Id], [m].[Name], [m].[TimeStamp], [t0].[Id], [t0].[CarId], [t0].[CustomerId], [t0].[TimeStamp], [t0].[Id0], [t0].[TimeStamp0], [t0].[FirstName], [t0].[FullName], [t0].[LastName], [t0].[Id1]FROM [dbo].[Inventory] AS [i] INNER JOIN [dbo].[Makes] AS [m] ON [i].[MakeId]=[m].[Id] LEFT JOIN(SELECT [o].[Id], [o].[CarId], [o].[CustomerId], [o].[TimeStamp], [c].[Id] AS [Id0], [c].[TimeStamp] AS [TimeStamp0], [c].[FirstName], [c].[FullName], [c].[LastName], [t].[Id] AS [Id1] FROM [dbo].[Orders] AS [o] INNER JOIN(SELECT [i0].[Id], [i0].[IsDrivable] FROM [dbo].[Inventory] AS [i0] WHERE [i0].[IsDrivable]=CAST(1 AS BIT)) AS [t] ON [o].[CarId]=[t].[Id] INNER JOIN [dbo].[Customers] AS [c] ON [o].[CustomerId]=[c].[Id] WHERE [t].[IsDrivable]=CAST(1 AS BIT)) AS [t0] ON [i].[Id]=[t0].[CarId] WHERE([i].[IsDrivable]=CAST(1 AS BIT))AND EXISTS (SELECT 1 FROM [dbo].[Orders] AS [o0] INNER JOIN(SELECT [i1].[Id], [i1].[Color], [i1].[IsDrivable], [i1].[MakeId], [i1].[PetName], [i1].[TimeStamp] FROM [dbo].[Inventory] AS [i1] WHERE [i1].[IsDrivable]=CAST(1 AS BIT)) AS [t1] ON [o0].[CarId]=[t1].[Id] WHERE([t1].[IsDrivable]=CAST(1 AS BIT)) AND([i].[Id]=[o0].[CarId]))ORDER BY [i].[Id], [m].[Id], [t0].[Id], [t0].[Id1], [t0].[Id0];Разделение запросов к связанным данным
Чем больше соединений добавляется в запрос LINQ, тем сложнее становится результирующий запрос. В версии EF Core 5 появилась возможность выполнять сложные соединения как разделенные запросы. Детальное обсуждение ищите в предыдущей главе, но вкратце помещение в запрос LINQ вызова метода
AsSplitQuery()