2009-09-28 47 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] 

就效率而言,測試將是找出最適合您的最高性能方法的最佳方法情況。