LINQ上有点生疏 我想从给定用户的相关表中获得单个结果。见下面的架构。 每个用户都有一个或多个角色。我想要一个用户名列表和一个自定义字符串,它是一种格式,例如“Role1 - Role2 - Role3”,其值是与该用户的UserRole / Role相关联的RoleNames。
Role
=====
RoleId
RoleCode
RoleName
UserRole
========
UserRoleId
RoleId
UserId
Users
======
UserId
UserName
在LINQpad中测试它,我可以获得用户名及其角色的列表,但是我想要结果中的单个字段是所有用户角色的格式化字符串,而不是RoleName,如上所述。< / p>
这是我现在拥有的。如何构建每个用户的角色列表?
from u in Users
join ur in UserRoles on u.UserId equals ur.UserKey
join r in Roles on ur.RoleKey equals r.RoleId
select new {
u.UserId,
u.UserName,
r.RoleName
}
答案 0 :(得分:0)
将RoleName
分组到UserName
上并使用String.Join来获得所需的结果。
from u in Users
join ur in UserRoles on u.UserId equals ur.UserKey
join r in Roles on ur.RoleKey equals r.RoleId
group r.RoleName by u.UserName into grp
select new {
UserName = grp.Key,
Roles = String.Join(" - ", grp)
};
这不会返回UserIds。如果它们对结果很重要,则需要将代码更改为
.... join as above
group r.RoleName by new {u.UserId, u.UserName} into grp
select new {
grp.Key.UserName,
grp.Key.UserId,
Roles = String.Join(" - ", grp)
};
这将创建一个包含UserId和UserName的分组键,因此您可以在选择中使用该键。
答案 1 :(得分:0)
按UserName将组添加到LINQ查询中,并使用string.Join格式化由“ - ”分隔的角色。
您可以在LINQPad中测试 -
var Roles = new [] {new{RoleId=1,RoleCode="SU",RoleName="Super User"},new{RoleId=2,RoleCode="PU",RoleName="Power User"}};
var Users = new [] {new{UserId=1,UserName="Bit Shift"},new{UserId=2,UserName="Edward"}};
var UserRoles = new [] {new{UserRoleId=1,RoleId=1,UserId=1},new{UserRoleId=2,RoleId=2,UserId=1},new{UserRoleId=3,RoleId=2,UserId=2}};
var userRoles = from u in Users
join ur in UserRoles on u.UserId equals ur.UserId
join r in Roles on ur.RoleId equals r.RoleId
select new
{
u.UserId,
u.UserName,
r.RoleName
}
into userRole
group userRole by userRole.UserName into userGroups
select new{ UserName=userGroups.Key, Roles = string.Join(" - ", userGroups.Select(ug => ug.RoleName))};
userRoles.Dump();
更简洁的版本,其中包括结果中的UserId + UserName -
var userRoles = 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 userGroups
select new{ User=userGroups.Key, Roles = string.Join(" - ", userGroups.Select(r => r.RoleName))};
userRoles.Dump();
对SQL数据库执行时,需要将查询拆分为两部分,因为LINQ to SQL不支持String.Join,如下所示 -
var userRoleGroups = (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 userGroups select userGroups)
.ToList(); // This causes SQL to be generated and executed
var userRoles = from userGroups in userRoleGroups select(new{ User=userGroups.Key, Roles = string.Join(" - ", userGroups.Select(r => r.RoleName))});
userRoles.Dump();
或者尝试使用Aggregate而不是String.Join,正如您所建议的那样 -
var userRoles = 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 userGroups
select(new{
User=userGroups.Key,
Roles = userGroups.Select(s => s.RoleName).Aggregate((current, next) => current + " - " + next)});
userRoles.Dump();