C# Linq合并左连接数据
假设我有以下数据库:C# Linq合并左连接数据,c#,linq,C#,Linq,假设我有以下数据库: Users ------- UserId (PK) UserName Roles ----- RoleId (PK) RoleName UserRoles --------- UserId (PK) RoleId (PK) 用户1-M用户角色M-1角色 使用LinqToSQL,我想返回以下集合: [User1], [Role1, Role2, Role3] [User2], [Role2, Role3] [User3], [] 等等 创建此LinqToSql查询的最
Users
-------
UserId (PK)
UserName
Roles
-----
RoleId (PK)
RoleName
UserRoles
---------
UserId (PK)
RoleId (PK)
用户1-M用户角色M-1角色
使用LinqToSQL,我想返回以下集合:
[User1], [Role1, Role2, Role3]
[User2], [Role2, Role3]
[User3], []
等等
创建此LinqToSql查询的最有效方法是什么
另外,如果我想创建一个过滤器,只返回拥有Role1的用户,那需要什么呢
Thx.定义“高效”。但除此之外
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
或者通过一些其他的角色
属性,比如说,名称
:
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
}
这是我将构造的一个查询,以便一次获得所需的结果集
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]
看起来它生成了更好的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]
就效率而言,测试将是找出最适合您的情况的最佳方法。我对LINQ to SQL一点也不熟悉,但我不相信这是正确的。难道
u.UserRoles
不表明UserRoles
是用户表上的一个字段吗?根本不是。当另一个表通过外键引用此表时,L2S会自动创建集合类型“导航属性”。只要UserRole
table将UserID
设置为FK toUser
table,为User
生成的实体类将有一个名为UserRoles
的属性。我如何按角色id进行筛选?我认为我可以将两个“查询”合并为一个?您的意思是要使用第一个查询,但也要进行筛选?是的,您可以,但在这种情况下,您希望将.Any()
替换为.Where()
,将其插入.Select()
之前。有没有办法摆脱Pavel查询中的子查询?谢谢