ToListAsync()
в конце достаточно. Выражения внутри запроса используются EF для составления запроса. Они не «выполняются» как SQL, как если бы они были как отдельные операторы для DbSets.
Например, когда я запускаю нечто подобное:
var parents = await context.Parents
.Select(x => new
{
x.ParentId,
x.Name,
Children = x.Children.Select(c => new { c.ChildId, c.Name }).ToList(),
ChildCount = x.Children.Count()
}).ToListAsync();
в тесте и установите точку останова при запущенном профилировщике. Оператор создает один оператор SQL:
SELECT
[Project2].[ParentId] AS [ParentId],
[Project2].[Name] AS [Name],
[Project2].[C2] AS [C1],
[Project2].[C1] AS [C2],
[Project2].[ChildId] AS [ChildId],
[Project2].[Name1] AS [Name1]
FROM ( SELECT
[Project1].[ParentId] AS [ParentId],
[Project1].[Name] AS [Name],
[Extent3].[ChildId] AS [ChildId],
[Extent3].[Name] AS [Name1],
CASE WHEN ([Extent3].[ChildId] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1],
[Project1].[C1] AS [C2]
FROM (SELECT
[Extent1].[ParentId] AS [ParentId],
[Extent1].[Name] AS [Name],
(SELECT
COUNT(1) AS [A1]
FROM [dbo].[Children] AS [Extent2]
WHERE [Extent1].[ParentId] = [Extent2].[ParentId]) AS [C1]
FROM [dbo].[Parents] AS [Extent1] ) AS [Project1]
LEFT OUTER JOIN [dbo].[Children] AS [Extent3] ON [Project1].[ParentId] = [Extent3].[ParentId]
) AS [Project2]
ORDER BY [Project2].[ParentId] ASC, [Project2].[C1] ASC
go
Не три запроса, которые могут вас заинтересовать, заблокируют. Это было при просмотре свойств навигации для связанных записей.
Больший вопрос, который я увидел, глядя на ваш пример для двойной проверки, был такой строкой:
LastVotedAt = _context.PollVotes.Where(vote=>vote.PollId == poll.Id).Select(vote => vote.VoteDate).SingleOrDefault()
Как это будет go вернуться непосредственно к контексту, а не получить доступ к голосам через коллекцию на опросе. Но я тоже это попробовал, и это все равно привело к одному запросу.
Children = x.Children.Select(c => new { c.ChildId, c.Name }).ToList(),
ChildCount = x.Children.Count(),
YoungestChild = context.Children.OrderBy(c=>c.BirthDate).Where(c=>c.ParentId == x.ParentId).FirstOrDefault()
В моем тестовом примере я go вернулся в контекст, чтобы получить младшего потомка для родительской записи, а не для дочерних элементов. свойство навигации. В этом случае он по-прежнему выполняется как 1 запрос.
Для подобных вопросов я определенно рекомендую создать проект песочницы для экспериментов EF с локальной базой данных, а затем использовать инструмент профилирования и SQL для наблюдения за операторами SQL. производится и когда они выполняются. Asyn c полезен для запросов, выполнение которых, как ожидается, займет некоторое время, но его следует использовать экономно, поскольку они могут снизить общую производительность запросов, выполняемых при каждом тривиальном запросе.