2009-09-28 50 views
3

说我有以下数据库:LINQ的结合左联接数据

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

Roles 
----- 
RoleId (PK) 
RoleName 

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

用户1-M的UserRole M-1作用

使用LinqToSQL,我想回到下面的一组:

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

等......

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

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

Thx。

回答

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 
} 
+0

我并不熟悉LINQ to SQL,但我不相信这是正确的。 'u.UserRoles'不会提示'UserRoles'是用户表中的一个字段? – Tinister 2009-09-28 18:01:28

+1

完全没有。当另一个表通过外键引用此表时,L2S会自动创建集合类型的“导航属性”。只要'UserRole'表的'UserID'设置为'User'的FK,为'User'生成的实体类将拥有一个名为'UserRoles'的属性。 – 2009-09-28 18:33:07

+0

我将如何过滤角色ID? – zzz 2009-09-28 20:36:51

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] 

就效率而言,测试将是找出最适合您的最高性能方法的最佳方法情况。