如何使用三个表在C#中执行外部连接

时间:2018-01-19 09:34:54

标签: c# asp.net linq linq-to-sql

我想获取每个角色中的角色列表和用户总数。到目前为止,这有效:

var result = (from r in _context.UserRoles
                          join u in _context.Users on r.UserId equals u.Id
                          group new { r, u } by new { r.RoleId } into grp
                          select new UserRoleModel { RoleId = (int)grp.FirstOrDefault().r.RoleId, NoOfUsers = grp.Count() }).ToList();

但它不会显示没有任何用户的角色。我有12个角色,其中7个已分配给至少一个用户,而其余5个没有。我想显示分配给它们的用户数量的所有角色,但是如果角色没有分配给它们的用户(如那5个),我希望它返回0作为用户数。感谢

2 个答案:

答案 0 :(得分:1)

您想申请left join,您应该使用DefaultIfEmpty加入他们。

此外,在查询中加入的实体是错误的。因为,如果要检索已分组的角色和相对用户的数量,则应将联结实体(UserRole)与Role实体联合,而不是User。否则,您永远不知道哪个角色没有用户。

var result = (from r in _context.Roles
    join ur in _context.UserRoles on r.Id equals ur.RoleId into ps
    from ur in ps.DefaultIfEmpty()
    group new { r,ur } by new { r.Id } into grp
    select new UserRoleModel { RoleId = (int)grp.Key.Id, 
    NoOfUsers = grp.Count(t => t.ur != null) }).ToList();

另外,我建议你改变

(int)grp.FirstOrDefault().r.RoleId

(int)grp.Key.RoleId

查询已按RoleId分组。

另外,我还有其他说明。我强烈建议您定义导航属性并使用它们。如果你想在实体中使用它们,那么查询会更简单;

var result = _context.Roles.Select(x => new UserRoleModel
{
    RoleId = x.Id,
    NoOfUsers = x.UserRoles?.Count() ?? 0
});

答案 1 :(得分:0)

试试这个,

var result = (from r in _context.UserRoles
         join u in _context.Users on r.UserId equals u.Id into temp
         from uu in temp.DefaultIfEmpty()
         group new { r, u } by new { r.RoleId } into grp
         select new UserRoleModel { RoleId = (int)grp.FirstOrDefault().r.RoleId, NoOfUsers = grp.Count() }).ToList();