使用ASP.NET标识检索多个用户,包括使用EF Core的角色

时间:2018-03-23 21:28:58

标签: c# asp.net-core asp.net-identity entity-framework-core

我尝试检索多个用户,包括他们的角色。这在论坛中使用,我想在其中显示评论该线程的用户的角色。我已经看过许多使用IdentityUserUserManager检索单个RoleManager角色的示例,但如上所述,我有多个用户希望检索。

我尝试将角色作为属性包含在用户中,如下所示:

public virtual ICollection<IdentityUserRole<string>> Roles { get; set; }

但这似乎不起作用。我尝试跳过多对多表,只需将角色实体直接包含在我的用户中,如下所示:

public virtual ICollection<IdentityRole> Roles { get; set; }

也没有区别,仍然无法奏效。基本上我只想加入角色给用户,但我不确定如何。

包含IdentityUserRole<string>属性并检索我的用户,会出现以下错误:

  

未知栏&#39; x.UserProfile.Roles.UserId1&#39;在&#39;字段列表&#39;

这是我的选择:

comments = _context.Comments
    .Include(x => x.UserProfile)
    .Include(x => x.UserProfile.Roles)
    .OrderBy(x => x.CreateDate)
    .Where(x => x.ThreadId == id && !user.IgnoredUsers.Contains(x.UserProfile.UserName))
    .ToPagedList(Constants.PAGER_DEFAULT_SMALL, page);

2 个答案:

答案 0 :(得分:1)

前几天我刚遇到这个问题。我找到了一些资源,说我应该在ApplicationUser对象中建立关系并设置道具,但我不想沿着那条路走下去。我最后只使用LINQ查询表达式来构建我需要的数据。

var usersWithRoles = (
  from u in _db.Users
  select new
  {
    Id = u.Id,
    Email = u.Email,
    Roles = (
      from ur in _db.UserRoles
      join r in _db.Roles on ur.RoleId equals r.Id
      where ur.UserId == u.Id
      select r.Name).ToArray()
  });

编辑:这假设您希望角色名称在字符串数组中。如果您在扩展此查询以满足您的需求时遇到问题,请发表评论,我会尽力帮助您。

编辑:下面的查询应该更接近您的用例。我无法测试查询,所以如果您遇到任何错误,请告诉我

public class CommentViewModel
{
    public virtual Comment Comment { get; set; }
    public virtual UserProfile User { get; set; }
    public virtual ICollection<Role> Roles { get; set; }
}

var comments = (
  from c in _context.Comments
  join u in _context.UserProfiles on c.UserId equals u.Id
  select new CommentViewModel
  {
    Comment = c,
    User = u,
    Roles = (
      from ur in _context.UserRoles
      join r in _context.Roles on ur.RoleId equals r.Id
      where ur.UserId == u.Id
      select r)
  });

答案 1 :(得分:0)

您不需要为角色添加导航属性;通过ApplicationUser的继承,已经存在于IdentityUser。该属性为UserRoles,它是IdentityUserRole的集合,它本身只是代表IdentityUserIdentityRole之间的M2M的实体。长短:

var users = db.Users.Include(x => x.UserRoles).Where(...);

不幸的是,由于IdentityUserRole没有导航属性,因此没有直接在这里实际获取角色的方法。因此,您需要单独的查询来获取角色:

var usersRoleIds = users.SelectMany(x => x.UserRoles).Select(x => x.RoleId);
var usersRoles = db.Roles.Where(x => userRoleIds.Contains(x));

最后,您可以通过以下方式获得任何一个特定用户的角色:

var specificUserRoles = usersRoles.Where(x => specificUser.UserRoles.Select(r => r.RoleId).Contains(x.Id));

它并不完全 easy ,但您可以将所有这些代码分解为某种映射实用程序类,并返回一个&#34; user&#34;查看已附加角色的模型。