У меня есть две сущности, User и UserPermission. Сущность User содержит все ваши обычные поля, Id, Username, Email и т. Д., А сущность UserPermission имеет два значения: UserId и PermissionId. Я написал метод репозитория GetUserWithPermissions, который первоначально использовал расширение Include и сделал что-то вроде этого:
return dbContext.Users.Include(u => u.UserPermission).Where(u => u.Username.Equals(username)).FirstOrDefault();
Это прекрасно работает, но проблема в том, что будет множество сущностей UserPermission, связанных с любым данным пользователем, и использование расширения Include по существу просто сводит две таблицы в одну, поэтому ВСЕ пользовательские поля повторяются для каждого отдельного пользователя. UserPermission, связанный с пользователем. Возвращенные данные выглядят примерно так:
Id Username Email ... PermissionId
1 johndoe john@email.com 1
1 johndoe john@email.com 2
1 johndoe john@email.com 3
1 johndoe john@email.com 4
1 johndoe john@email.com 5
1 johndoe john@email.com 6
1 johndoe john@email.com 7
Единственная разница между каждой строкой - последний столбец PermissionId. Если у нас есть 50 разрешений, определенных для пользователя, это большой кусок повторяющихся данных, возвращаемых, когда я не думаю, что это необходимо. Очевидно, что другой мой вариант - сделать что-то вроде этого:
User user = dbContext.Users.Where(u => u.Username.Equals(username)).FirstOrDefault();
if (user != null)
user.UserPermissions.ToList();
return user;
Приведенный выше код выполняет то же самое, возвращая значительно меньше данных, но с компромиссом, заключающимся в двух поездках в базу данных.
Какой метод лучше? Возвращать много повторяющихся данных или совершать две поездки в базу данных?
Вот SQL-запрос, сгенерированный Entity Framework
SELECT
[Project2].[Id] AS [Id],
[Project2].[Username] AS [Username],
[Project2].[LoweredUsername] AS [LoweredUsername],
[Project2].[CompanyId] AS [CompanyId],
[Project2].[FirstName] AS [FirstName],
[Project2].[LastName] AS [LastName],
[Project2].[Email] AS [Email],
[Project2].[C1] AS [C1],
[Project2].[UserId] AS [UserId],
[Project2].[PermissionValue] AS [PermissionValue]
FROM ( SELECT
[Limit1].[Id] AS [Id],
[Limit1].[Username] AS [Username],
[Limit1].[LoweredUsername] AS [LoweredUsername],
[Limit1].[CompanyId] AS [CompanyId],
[Limit1].[FirstName] AS [FirstName],
[Limit1].[LastName] AS [LastName],
[Limit1].[Email] AS [Email],
[Extent2].[UserId] AS [UserId],
[Extent2].[PermissionValue] AS [PermissionValue],
CASE WHEN ([Extent2].[PermissionValue] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1]
FROM (SELECT TOP (1)
[Extent1].[Id] AS [Id],
[Extent1].[Username] AS [Username],
[Extent1].[LoweredUsername] AS [LoweredUsername],
[Extent1].[CompanyId] AS [CompanyId],
[Extent1].[FirstName] AS [FirstName],
[Extent1].[LastName] AS [LastName],
[Extent1].[Email] AS [Email]
FROM [dbo].[Users] AS [Extent1]
WHERE [Extent1].[LoweredUsername] = (LOWER(LTRIM(RTRIM(@p__linq__0)))) ) AS [Limit1]
LEFT OUTER JOIN [dbo].[UserPermissions] AS [Extent2] ON [Limit1].[Id] = [Extent2].[UserId]
) AS [Project2]
ORDER BY [Project2].[Id] ASC, [Project2].[C1] ASC
Спасибо
Ник