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 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;
    ...
}