Blazor WASM与ASP.NET Core中如何获取带多角色的Identity用户列表?
解决ASP.NET Core Identity用户与多角色关联展示问题
你当前的查询思路本身没问题,但因为用户和角色是一对多的关联关系,直接三表Join会生成重复的用户记录——每个角色对应一条用户数据。要实现每个用户仅出现一次并附带角色列表,需要对查询结果做分组聚合,或者利用EF Core的导航属性简化操作,下面是两种可行方案:
方案一:基于原查询的分组聚合
先通过Join获取所有用户-角色关联数据,再在内存中按用户分组,将同一用户的角色聚合为列表:
var userRolesRaw = await (from user in context.Users join userRoles in context.UserRoles on user.Id equals userRoles.UserId join role in context.Roles on userRoles.RoleId equals role.Id select new { user.Id, user.UserName, role.Name }).ToListAsync(); var listado = userRolesRaw .GroupBy(x => new { x.Id, x.UserName }) .Select(g => new { UserId = g.Key.Id, UserName = g.Key.UserName, Roles = g.Select(x => x.Name).ToList() }) .ToList();
方案二:利用EF Core导航属性(推荐)
ASP.NET Core Identity的DbContext默认已经配置了用户与角色的导航属性,直接通过Include和ThenInclude加载关联数据,再投影出包含角色列表的对象,代码更简洁且符合EF Core的使用习惯:
var listado = await context.Users .Include(u => u.UserRoles) .ThenInclude(ur => ur.Role) .Select(u => new { UserId = u.Id, UserName = u.UserName, Roles = u.UserRoles.Select(ur => ur.Role.Name).ToList() }) .ToListAsync();
如果需要包含没有分配任何角色的用户,这个方案会自动保留这类用户(其Roles为空列表);如果只需要获取有角色的用户,可以在查询中添加Where(u => u.UserRoles.Any())过滤。
注意事项
使用方案二时,确保你的IdentityUser派生类中正确声明了导航属性:
public class ApplicationUser : IdentityUser { public virtual ICollection<IdentityUserRole<string>> UserRoles { get; set; } = new List<IdentityUserRole<string>>(); }
IdentityUserRole的默认实现已经包含了Role导航属性,无需额外配置。
内容的提问来源于stack exchange,提问作者Jasiel Torres
相关产品推荐
相关产品推荐

