Linq Combine Left Join Data

Let's say I have the following database:

Users
-------
UserId (PK)
UserName

Roles
-----
RoleId (PK)
RoleName

UserRoles
---------
UserId (PK)
RoleId (PK)

Users 1-M UserRoles M-1 Roles

Using LinqToSQL, I want to return the following set:

[User1], [Role1, Role2, Role3]
[User2], [Role2, Role3]
[User3], []

Etc ...

What is the most efficient way to create this LinqToSql query?

Also, if I want to create a filter to only return users with Role1, what would it cause?

thanks.

+3
source share
2 answers

Define "effective." But otherwise ...

from u in dataContext.Users
select new { User = u, Roles = u.UserRoles.Select(ur => ur.Role) }

And filtering users using RoleID:

from u in dataContext.Users
where u.UserRoles.Any(ur => ur.RoleID == 1)
select u

Or some other attribute Role, say Name:

from u in dataContext.Users
where u.UserRoles.Any(ur => ur.Role.Name == "Role 1")
select u

Putting it all together:

from u in dataContext.Users
select new
{
     User = u,
     Roles = from ur in u.UserRoles
             where ur.RoleID == 1 || ur.Role.Name == "Role 1"
             select ur.Role
}
+4
source

This is the only query I would build in order to immediately get the desired result.

from u in Users
join ur in UserRoles on u.UserId equals ur.UserId
join r in Roles on ur.RoleId equals r.RoleId
group r by u into grouping
select grouping

SQL:

SELECT [t0].[UserId], [t0].[Username]
FROM [Users] AS [t0]
INNER JOIN [UserRoles] AS [t1] ON [t0].[UserId] = [t1].[UserId]
INNER JOIN [Roles] AS [t2] ON [t1].[RoleId] = [t2].[RoleId]
GROUP BY [t0].[UserID], [t0].[Username]
GO

-- Region Parameters
DECLARE @x1 Int = 2
-- EndRegion
SELECT [t2].[RoleId], [t2].[RoleName]
FROM [Users] AS [t0]
INNER JOIN [UserRoles] AS [t1] ON [t0].[UserId] = [t1].[UserId]
INNER JOIN [Roles] AS [t2] ON [t1].[RoleId] = [t2].[RoleId]
WHERE @x1 = [t0].[UserId]

@Pavel : SQL:

SELECT [t0].[UserId], [t0].[Username], [t2].[RoleId], [t2].[RoleName] (
    SELECT COUNT(*)
    FROM [UserRoles] AS [t3]
    INNER JOIN [Roles] AS [t4] ON [t4].[RoleId] = [t3].[RoleId]
    WHERE [t3].[UserId] = [t0].[UserId]
    ) AS [value]
FROM [Users] AS [t0]
LEFT OUTER JOIN ([UserRoles] AS [t1]
    INNER JOIN [Roles] AS [t2] ON [t2].[RoleId] = [t1].[RoleId]) ON [t1].[UserId] = [t0].[UserId]
ORDER BY [t0].[UserId], [t1].[UserRoleId], [t2].[RoleId]

, , .

+1

Source: https://habr.com/ru/post/1718733/


All Articles