Литмир - Электронная Библиотека
A
A

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()
класса, производного от
DbContext
. При загрузке сущностей на стороне "многие" отношения "один ко многим" используйте вызов метода
Collection()
на результате
Entry()
. Чтобы загрузить сущности на стороне "один" отношения "один ко многим" (или отношения "один к одному"), применяйте метод
Reference()
. Вызов метода
Query()
на результате
Collection()
или
Reference()
возвращает экземпляр реализации
IQueryable<T>
, который можно использовать для получения строки запроса (как видно в приводимых далее тестах) и для управления фильтрами запросов (как показано в следующем разделе). Чтобы выполнить запрос и загрузить запись (записи), вызовите метод
Load()
на результате метода
Collection()
,
Reference()
или
Query()
. Выполнение запроса начнется немедленно после вызова
Load()
.

Представленный ниже тест (из

CarTests.cs
) демонстрирует, каким образом загрузить связанные данные через навигационное свойство типа ссылки внутри сущности
Car
:

[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 =&gt; 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 =&gt; x.Id == 1);

  Assert.Empty(car.Orders);

  var query = Context.Entry(car).<b>Collection(c =&gt; 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)]

466
{"b":"847442","o":1}