Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю
SELECT [m].[Id], [m].[Name], [m].[TimeStamp], [t].[Id], [t].[Color], [t].[IsDrivable], [t].[MakeId], [t].[PetName], [t].[TimeStamp]FROM [dbo].[Makes] AS [m]LEFT JOIN ( SELECT [i].[Id], [i].[Color], [i].[IsDrivable], [i].[MakeId], [i].[PetName], [i].[TimeStamp] FROM [dbo].[Inventory] AS [i] WHERE [i].[Color] = N'Yellow') AS [t] ON [m].[Id] = [t].[MakeId]ORDER BY [m].[Id], [t].[Id]Изменение запроса на разделенный приводит к выдаче такого кода SQL (получен с использованием профилировщика SQL Server):
SELECT [m].[Id], [m].[Name], [m].[TimeStamp]FROM [dbo].[Makes] AS [m]ORDER BY [m].[Id]SELECT [t].[Id], [t].[Color], [t].[IsDrivable], [t].[MakeId], [t].[PetName], [t].[TimeStamp], [m].[Id]FROM [dbo].[Makes] AS [m]INNER JOIN ( SELECT [i].[Id], [i].[Color], [i].[IsDrivable], [i].[MakeId], [i].[PetName], [i].[TimeStamp] FROM [dbo].[Inventory] AS [i] WHERE [i].[Color] = N'Yellow') AS [t] ON [m].[Id] = [t].[MakeId]ORDER BY [m].[Id]Явная загрузка связанных данных
Если связанные данные нужно загрузить сразу после того, как главная сущность была запрошена в память, то связанные сущности можно извлечь из базы данных с помощью последующих обращений к базе данных. Это запускается с применением метода
Entry()DbContextCollection()Entry()Reference()Query()Collection()Reference()IQueryable<T>Load()Collection()Reference()Query()Load()Представленный ниже тест (из
CarTests.csCar[Fact]public void ShouldGetReferenceRelatedInformationExplicitly(){ var car = Context.Cars.First(x => x.Id == 1); Assert.Null(car.MakeNavigation); var query = Context.Entry(car).<b>Reference(c => c.MakeNavigation)</b>.Query(); var qs = query.ToQueryString(); query.<b>Load()</b>; Assert.NotNull(car.MakeNavigation);}Вот сгенерированный код SQL:
DECLARE @__p_0 int = 1;SELECT [m].[Id], [m].[Name], [m].[TimeStamp]FROM [dbo].[Makes] AS [m]WHERE [m].[Id] = @__p_0В следующем тесте показано, как загрузить связанные данные через навигационное свойство типа коллекции внутри сущности
Car[Fact]public void ShouldGetCollectionRelatedInformationExplicitly(){ var car = Context.Cars.First(x => x.Id == 1); Assert.Empty(car.Orders); var query = Context.Entry(car).<b>Collection(c => c.Orders)</b>.Query(); var qs = query.ToQueryString(); query.<b>Load()</b>; Assert.Single(car.Orders);}Сгенерированный код SQL выглядит так:
DECLARE @__p_0 int = 1;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)) AND ([o].[CarId] = @__p_0)Явная загрузка связанных данных с фильтрами запросов
Глобальные фильтры запросов активны не только при формировании запросов, генерируемых для энергичной загрузки связанных данных, но и при явной загрузке связанных данных. Добавьте (в
MakeTests.cs[Theory][InlineData(1,1)]