LINQ JOIN用于集合中的集合
本文关键字:集合 用于 JOIN LINQ | 更新日期: 2023-09-27 18:17:06
我有一个名为Users的表,Id为主键,另一个名为Roles的表,Id为主键,还有一个名为UserRoles的表,有两个外键User_Id和Role_Id。
在我的代码中,我有一个名为Role的类:
public partial class Role
{
public virtual int Id {get;set;}
public virtual string RoleName {get;set;}
}
我有另一个名为User的类:
public partial class User
{
private ICollection<Role> _userRoles;
...All Properties...
public virtual ICollection<Role> UserRoles
{
get { return _userRoles ?? (_userRoles = new List<Role>()); }
protected set { _userRoles = value; }
}
}
类的映射是正确定义的,所以当我得到一个用户时,我得到了他/她所属的角色。现在我想在网格列表中显示角色列表,并希望显示每个角色对应的用户数量。
我已经尝试使用join,但是我无法到达结果。
有什么最好的办法吗?提前感谢
您可以使用Linq中的Aggregate函数:
var users = new List<User>();
var roles = new List<Role>();
//Populate users and roles
var rolesAndUsers = new Dictionary<Role, List<User>>();
users.Aggregate(rolesAndUsers, (d, u) =>
{
ICollection<Role> userRoles = u.UserRoles;
foreach (var userRole in userRoles)
{
if (!d.ContainsKey(userRole))
d.Add(userRole, new List<User>());
d[userRole].Add(u);
}
return d;
});
为Role
添加导航属性:
public partial class Role
{
public virtual int Id {get;set;}
public virtual string RoleName {get;set;}
public virtual ICollection<User> Users { get; set; } // Here
}
然后简单地查询每个角色的用户数:
var query = from r in context.Roles
select new {
r.RoleName,
UsersCount = r.Users.Count()
};
生成的SQL看起来像
SELECT [Extent1].[Id] AS [Id],
[Extent1].[RoleName] AS [RoleName],
(SELECT COUNT(1) AS [A1]
FROM [dbo].[UserRoles] AS [Extent2]
WHERE [Extent1].[Id] = [Extent2].[Role_Id]) AS [C1]
FROM [dbo].[Roles] AS [Extent1]
如您所见,将为每个角色生成子查询。运行它,看看性能在您的情况下是否可以接受。
您可以合并内部角色列表,然后将列表按角色分组,然后获得每个组的计数。
List<User> users = ...;
var roleCounts = users.SelectMany(user => user.UserRoles)
.GroupBy(role => role)
.Select(roleGroup => new {Role = roleGroup.Key, Count = roleGroup.Count());
foreach (var roleCount in roleCounts)
{
Role role = roleCount.Role;
int count = roleCount.Count;
...
}