You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过一次数据库调用加载带角色的ASP.NET Core Identity用户

如何一次性加载所有ASP.NET Core Identity用户及其角色

现有加载所有Identity用户的方法:

await _userManager.Users.ToListAsync()

加载特定用户角色的方法:

IList<string> userRoles = await UserManager.GetRolesAsync(userId);

但如果要加载所有用户并在DTO中返回其角色,循环每个用户查询数据库的方式效率极低,请问是否有办法一次性获取这两类信息?

当然可以,通过EF Core的关联数据加载或直接编写LINQ查询,就能一次性从数据库获取所有用户及其关联角色,彻底避免N+1查询的低效问题。以下是两种可行方案:

方案1:使用Include和ThenInclude加载关联数据

ASP.NET Core Identity的User实体默认包含UserRoles导航属性,通过它可以关联到Role实体。直接在查询中包含这些关联数据即可:

// 一次性加载所有用户及其关联角色
var usersWithRoles = await _userManager.Users
    .Include(u => u.UserRoles)
    .ThenInclude(ur => ur.Role)
    .ToListAsync();

// 投影到自定义DTO(示例)
var userDtos = usersWithRoles.Select(u => new UserDto
{
    Id = u.Id,
    UserName = u.UserName,
    Email = u.Email,
    Roles = u.UserRoles.Select(ur => ur.Role.Name).ToList()
}).ToList();

方案2:直接通过数据库上下文联表查询

如果项目自定义了ApplicationDbContext,可以直接对Users、UserRoles、Roles三张表做联表查询,再分组投影到DTO:

var usersWithRoles = await _context.Users
    .Join(_context.UserRoles, 
          user => user.Id, 
          userRole => userRole.UserId, 
          (user, userRole) => new { User = user, UserRole = userRole })
    .Join(_context.Roles, 
          ur => ur.UserRole.RoleId, 
          role => role.Id, 
          (ur, role) => new { ur.User, Role = role })
    .GroupBy(result => result.User)
    .Select(group => new UserDto
    {
        Id = group.Key.Id,
        UserName = group.Key.UserName,
        Email = group.Key.Email,
        Roles = group.Select(item => item.Role.Name).ToList()
    })
    .ToListAsync();

关键说明

  • 循环调用GetRolesAsync会触发N+1查询问题:加载所有用户需要1次查询,每个用户单独查角色又需要N次查询,数据库压力会随用户数量激增。
  • 上述两种方案均只需要1次数据库查询即可获取所有关联数据,性能提升显著。
  • 确保User实体已正确配置UserRoles导航属性(ASP.NET Core Identity默认已配置)。

内容的提问来源于stack exchange,提问作者Pawan Nogariya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 11:52:40