EF Core, готовый к загрузке проекционный сборник - PullRequest
0 голосов
/ 28 мая 2018

В ядре EF я пытаюсь спроецировать набор результатов с помощью подколлекции.

 ctx.As.Select(a => new
    {
        AId = a.Id,
        BNames = a.Bs.Select(x=>x.Name) //SubCollection
    })

Однако, когда это выполняется, коллекция BNames ленива, поэтому, когда она перечисляется, она запускает отдельный запрос длякаждый ряд.например, для 2 предметов в коллекции Б.

[a].[Id] AS [AId] FROM [As] AS [a]

p_executesql N'SELECT [x].[Name]
FROM [Bs] AS [x]
WHERE @_outer_Id = [x].[AId]',N'@_outer_Id int',@_outer_Id=1

p_executesql N'SELECT [x].[Name]
FROM [Bs] AS [x]
WHERE @_outer_Id = [x].[AId]',N'@_outer_Id int',@_outer_Id=2

В EF6 тот же запрос приводит к следующему (как я и ожидал):

SELECT 
[Extent1].[Id] AS [Id], 
[Project1].[C1] AS [C1], 
[Project1].[Name] AS [Name]
FROM  [dbo].[A] AS [Extent1]
LEFT OUTER JOIN  (SELECT 
    [Extent2].[Name] AS [Name], 
    [Extent2].[A_Id] AS [A_Id], 
    1 AS [C1]
    FROM [dbo].[B] AS [Extent2] ) AS [Project1] ON [Extent1].[Id] = [Project1].[A_Id]
ORDER BY [Extent1].[Id] ASC, [Project1].[C1] ASC

Как я могу получитьEF для загрузки подколлекции BNames?


Примечание: Это не та же проблема, что и при включении дочерних объектов с .Include, поскольку это пользовательская проекция, а не свойство навигации.Использование .Include здесь приводит к ошибке.

Полный код репо здесь: https://gist.github.com/lukemcgregor/692834629da09b21d5a35515e86c9002

1 Ответ

0 голосов
/ 28 мая 2018

Это возможно в EF Core 2.1 с использованием соответствующих оптимизаций подзапроса.

Вам необходимо обновить EF Core 2.1 и внести небольшую модификацию, чтобы включить оптимизацию, добавив .ToList() к подзапросу:

foreach (var thing in ctx.As
    .Select(a => new
    {
        AId = a.Id,
        BNames = a.Bs.Select(x => x.Name).ToList()
    }))

См. Оптимизация коррелированных подзапросов в Новые функции в EF Core 2.1 .

...