使用ASP Identity的UserManager时,如何关联其他实体?
解决ASP.NET Identity中UserManager无法Include关联实体的问题
下面提供几种可行的替代方案:
方案1:直接通过DbContext查询(最直观)
既然UserManager底层依赖DbContext,直接操作上下文结合角色关联查询,同时Include需要的导航属性即可:
// 获取Member角色用户并关联Projects、School var members = await _context.Users .Include(u => u.Projects) .Include(u => u.School) .Where(u => u.Roles.Any(r => r.Role.Name == "Member")) .ToListAsync(); // 获取Leader角色用户并关联Projects、School var leaders = await _context.Users .Include(u => u.Projects) .Include(u => u.School) .Where(u => u.Roles.Any(r => r.Role.Name == "Leader")) .ToListAsync();
注:如果你的角色关联是通过IdentityUserRole<TKey>,需确保上下文已正确配置角色导航属性,否则可能需要显式关联Roles表。
方案2:扩展UserManager添加带Include的方法
要是想继续沿用UserManager的封装逻辑,可以给它扩展一个支持Include的方法:
public static class UserManagerExtensions { public static async Task<IList<AppUser>> GetUsersInRoleWithIncludesAsync( this UserManager<AppUser> userManager, string roleName, params Expression<Func<AppUser, object>>[] includes) { var targetRole = await userManager.FindByNameAsync(roleName); if (targetRole == null) return new List<AppUser>(); var userQuery = userManager.Users .Where(u => u.Roles.Any(r => r.RoleId == targetRole.Id)); // 批量添加Include foreach (var includeExpr in includes) { userQuery = userQuery.Include(includeExpr); } return await userQuery.ToListAsync(); } }
使用时直接调用扩展方法:
var members = await _userManager.GetUsersInRoleWithIncludesAsync( "Member", u => u.Projects, u => u.School);
方案3:利用UserManager.Users属性构建查询
UserManager本身暴露了Users属性(IQueryable类型),可以直接基于它构建带Include的查询:
var memberRole = await _userManager.FindByNameAsync("Member"); var members = await _userManager.Users .Include(u => u.Projects) .Include(u => u.School) .Where(u => u.Roles.Any(r => r.RoleId == memberRole.Id)) .ToListAsync();
内容的提问来源于stack exchange,提问作者Feldmarshall
相关产品推荐
相关产品推荐

