Я пытаюсь выполнить запрос, подобный следующему:
SELECT r.*, (SELECT COUNT(UserID) FROM RoleUsers ru WHERE ru.RoleId = r.Id) AS Assignments
FROM Roles r
Чтобы получить количество пользователей для каждой роли.
Самый простой и простой способ реализовать желаемый результат:
this.DbContext.Set<Role>().Include(x => x.RoleUser)
.Select(x => new { x, Assignments = x.RoleUsers.Count() });
Извлекает все роли, а затем N запросов для получения количества:
SELECT COUNT(*)
FROM [dbo].[RoleUsers] AS [r0]
WHERE @_outer_Id = [r0].[RoleId]
Что вообще не вариант. Я также попытался использовать GroupJoin
, но он загружает все необходимые данные в одном запросе и выполняет группировку в памяти:
this.DbContext.Set<Role>().GroupJoin(this.DbContext.Set<RoleUser>(), role => role.Id,
roleUser => roleUser.RoleId, (role, roleUser) => new
{
Role = role,
Assignments = roleUser.Count()
});
Сгенерированный запрос:
SELECT [role].[Id], [role].[CustomerId], [role].[CreateDate], [role].[Description], [role].[Mask], [role].[ModifyDate], [role].[Name], [assignment].[UserId], [assignment].[CustomerId], [assignment].[RoleId]
FROM [dbo].[Roles] AS [role]
LEFT JOIN [dbo].[RoleUser] AS [assignment] ON [role].[Id] = [assignment].[RoleId]
ORDER BY [role].[Id]
Кроме того, я искал способ использования оконных функций, где я могу просто разделить счетчик по разделам и использовать разные роли, но я не знаю, как подключить оконную функцию в EF:
SELECT DISTINCT r.*, COUNT(ra.UserID) OVER(PARTITION BY ru.RoleId)
FROM RoleUsers ru
RIGHT JOIN Roles r ON r.Id = ru.RoleId
Итак, есть ли способ избежать EntitySQL?