【问题标题】:How to get the Role's Names for each user in a list?如何获取列表中每个用户的角色名称?
【发布时间】:2017-04-27 20:17:51
【问题描述】:

我正在尝试填充一个 RoleList,其中包含每个用户的角色名称。我在查询部分遇到问题。

我有 2 个表,IdentityUserRole 表具有 UserIdRoleId,然后 IdentityRoles 表具有RoleId,以及角色的Name

这是我目前所拥有的,它给我带来了多个问题。

public static IEnumerable<string> GetRolesByUserId(string userId)
{
    ApplicationDbContext db = new ApplicationDbContext();

    return db.Set<IdentityUserRole>().Where(r => r.UserId.Contains(userId)).Select(x => x.RoleId);
}

我最终会在此列表中调用GetRolesByUserId

private async Task<IEnumerable<UserViewModel>> GetUserData(ApplicationDbContext db)
{
  var users = db.Users;
  var list = await GetUsers(db, users);

var vmlist = list.Select(item => new UserViewModel()
{
    ID = item.ID,
    Username = item.Username,
    FirstName = item.FirstName,
    LastName = item.LastName,
    Email = item.Email,
    TaxID = item.TaxID,
    TaxIdHash = item.TaxIdHash,
    IV = item.IV,
    TaxIDEncrypted = item.TaxIDEncrypted,
    Active = item.Active,
    RoleList = GetRolesByUserId(item.ID),
    Roles = "",//string.Join(",", GetRolesByUserId(item.ID)).ToArray(),
    IsActive = item.IsActive,
    Status = item.Status
});

UserViewModel 的 RoleList 为

public List<string> RoleList { get; set; }

我对 c# 查询相当陌生,过去 3 天一直在尝试解决这个问题。如果有人可以帮助我解决这个问题,请。谢谢你。

【问题讨论】:

标签: c# sql-server linq


【解决方案1】:

关于查询部分,您需要以下内容:

public static List<string> GetRolesByUserId(string userId)
{
    var db = new ApplicationDbContext();

    var userRoles = from identityUserRole in db.Set<IdentityUserRole>
                    join identityRole in db.Set<IdentityRoles>
                    on identityUserRole.RoleId equals identityRole.RoleId
                    where identityUserRole.UserId == userId
                    select identityRole.Name;

    return userRoles.ToList();
}

上面是另一种声明LINQ查询的语法,它被称为查询语法,而您使用的语法被称为fluent语法。最后,编译器会将用查询语法编写的查询转换为用流畅语法编写的等效查询。我在这里使用 查询语法 的原因是,我认为在这种特殊情况下,查询比用 fluent 语法 编写的查询更具可读性。

为了记录,流利语法中的等效查询如下:

var userRoles = db.Set<IdentityUserRole>
                  .Join(db.Set<IdentityRoles>,
                        identityUserRole => identityUserRole.RoleId,
                        identityRole => identityRole.RoleId
                        (identityUserRole, identityRole) => { identityRole. Name })
                  .Where(x=>x.UserId == userId)
                  .ToList();

关于RolesRolesList 现在我有以下cmets。

由于Roles 可以直接从RoleList 计算,我建议您创建一个只有getter 的属性,如下所示:

public string Roles 
{
    get 
    { 
        if(RoleList == null || RoleList.Count == 0)
        {
            return null;
        }
        return string.Join(",", RoleList);
    }
}

【讨论】:

  • 当我运行它时,我在控制台中收到一个错误,提示 DbQuery' 不包含 'ToList' 的定义。
  • 你到底在运行什么“它”?
  • @Christos 当我在 RoleList = GetRolesByUserId(item.ID).ToList(); 中执行 ToList() 时,我收到此错误消息,无法隐式转换类型 'System.Data.Entity.Infrastructure。 DbQuery' 到 'System.Collections.Generic.List'。而且我无法从 UserViewModel 调用角色,因为它是吸气剂。它显示“它是只读的”。
  • @Truecolor 有两个选项。 1)在返回之前将方法的返回类型更改为List&lt;string&gt;并调用ToList 2)将方法的类型更改为IQueryable&lt;string&gt;并在方法调用之后调用ToList。请更新并让我知道。关于你不能从UserViewModel 拨打Roles 我不明白。由于Roles 是您模型的公共属性,因此您无法做到。可能我在这里想念一些东西。谢谢
  • 我将UserViewModel 中的方法类型和RoleList 类型都更改为IQueryable&lt;string&gt;,并且成功了。对于Roles,我在创建表格网格方法时调用了它,因为我不知道如何在列表中设置它。谢谢大家的帮助。真的很感激。
猜你喜欢
  • 2017-11-13
  • 2013-08-07
  • 1970-01-01
  • 1970-01-01
  • 2016-12-26
  • 2017-07-25
  • 1970-01-01
  • 2019-07-11
  • 2015-02-01
相关资源
最近更新 更多