Linq结合左连接数据

时间:2009-09-28 17:50:34

标签: c# linq

说我有以下数据库:

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

Roles
-----
RoleId (PK)
RoleName

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

用户1-M UserRoles M-1角色

使用LinqToSQL,我想返回以下集合:

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

等等...

创建此LinqToSql查询的最有效方法是什么?

此外,如果我想创建一个过滤器以仅返回具有Role1的用户,那会带来什么?

THX。

2 个答案:

答案 0 :(得分:4)

定义“高效”。但是否则......

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

RoleID过滤用户:

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

或者使用其他Role属性,例如Name

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

将它们组合在一起:

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
}

答案 1 :(得分:1)

这是我要构建的单个查询,以便一次性获得所需的结果集

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]

就有效性而言,测试将是了解最适合您的情况的最佳方法。