【问题标题】:Get user with assigned roles获取分配角色的用户
【发布时间】:2018-01-22 07:51:55
【问题描述】:

使用 ASP.NET Core 身份,我使用UserManager.CreateAsync() 创建一个新用户,并将他们分配给使用UserManager.AddToRoleAsync 的现有角色。这是可行的,因为用户和角色之间的关系存储在数据库的AspNetUserRoles 表中。

但是当我使用 UserManager(例如UserManager.FindByMail() 方法)获取用户时,Role 列表为空。我还尝试了 EF 的 Include 函数,如下所示:

var user = userManager.Users.Include(u => u.Roles).FirstOrDefault(u => u.Email == "test@test.de");

这给了我 n:m 关联表的 ID,这不是很有用,因为我需要角色名称。使用第二个查询加载它们也是不可能的,因为身份用户的Roles 属性是只读的。我希望得到一个List<string> 的角色名称。找不到有关此的任何信息。

对我来说,唯一的解决方法似乎是向我的用户添加一个自定义属性并用数据填充他们,我使用第二个查询来获取这些数据。但这不是一个好的解决方案。不敢相信 ASP.NET Core Identity 没有更好的方法来获取这些数据......

【问题讨论】:

  • 不要在标题中强行添加标签!

标签: asp.net-core asp.net-identity asp.net-core-mvc asp.net-core-1.0


【解决方案1】:

UserManager 默认不加载关系。

手动包含是一种好方法,但正如 here 所述 - EntityFramework Core 尚不支持直接 M:N 关系。

所以我看到有两种方式:

(首选)使用

    userManager.GetRolesAsync(user);

这将返回带有用户角色名称的List<string>。或者使用一些 EF 查询通过加入的 IdentityUserRole 获取 IdentityRole 对象。不幸的是,这需要接受角色不会直接在用户实体中这一事实。

或者您可以实现自定义IdentityUserRole,在那里创建与IdentityRole 的关系,然后使用`

查询它
Include(user => user.Roles).ThenInclude(role => role.Role)

描述了如何实现自己的身份实体,例如here。但这是一种复杂的方法,Role 对象将嵌套在绑定实体中。


但是,您可以在 ApplicationUser 中声明一个属性:

[NotMapped]
public List<string> RoleNames {get; set;}

并随意使用它...

【讨论】:

  • 我覆盖 IdentityUserRole(和所有其他身份类),然后使用 .Include(u => u.Roles).ThenInclude(r => r.Role) 但我收到错误 Invalid column name 'AppRoleId1 ' 从数据库获取结果时。有什么想法吗?
  • @Makla:列名“AppRoleId1”看起来很奇怪。您是否为更改生成了迁移?如果是,看起来还可以吗?
  • 错误消失,但 Role 属性为空:stackoverflow.com/questions/42388369/…
【解决方案2】:

这是我想出的解决方案。它可能不是最有效的。希望它可以帮助某人。

public class UserVM
{
    public string Id { get; set; }
    public string UserName { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
    public string Roles { get; set; }
}

// Project each element of query into List<UserVM>
var list = (from user in _userManager.Users
            select new UserVM
            {
                Id = user.Id,
                UserName = user.UserName,
                Name = user.Name,
                Email = user.Email
            }).ToList();

list.Select(async user =>
{
    var userEntity = await _userManager.FindByIdAsync(user.Id);
    user.Roles = string.Join("; ", await _userManager.GetRolesAsync(userEntity));
}).ToList();

【讨论】:

  • 这个解决方案肯定会消耗资源,尤其是在 sql server 来回查找每个用户角色时。假设我们有 50k 用户,每次加载时都会向 sql server 发出 50k 请求,无论如何都会将其关闭。
猜你喜欢
  • 2017-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-09
  • 1970-01-01
  • 2013-05-21
  • 1970-01-01
  • 2020-03-20
相关资源
最近更新 更多