This is the single query that I would construct to get your desired result set all at once
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
It produces the following 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's looks like it produces a better SQL statement:
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]
In terms of efficient, testing is going to be the best way to figure out what most performant approach is for your situation.