具有Identity 2.2.1中的角色列表的用户列表

时间:2015-12-02 19:47:30

标签: c# linq lambda asp.net-identity asp.net-identity-2

所以我一直在搜索Google和SO。这个问题的感觉已被多次询问,但没有答案对我有帮助,但我觉得我已经接近了。但是,我是LINQ和Lambda的新手,并且没有做我想做的事情的知识。

期望结果

User                   Roles
-----------------------------------------
John                   Admin
Jane                   Staff, HR, Payroll
MyCoolUserName         User

我与this postthis post非常接近。这是我到目前为止所得到的。

视图模型:

public class UsersViewModel {
    [Display(Name = "User")]
    public ApplicationUser User { get; set; }

    [Display(Name = "Roles")]
    public string Roles { get; set; }
}

控制器:

试验#1

此解决方案会返回角色的空白,我不得不将其添加到我的web.config文件中:<roleManager enabled="true" />

public class UsersController : Controller {
    public async Task Index() {
        var allUsers = await db.Users.ToListAsync();
        var users = new List();
        foreach (var user in allUsers) {
            String[] roles = Roles.GetRolesForUser(user.UserName);
            users.Add(new UsersViewModel {User = u, Roles = String.Join(",", roles.ToArray())});
        }
        return View(users);
    }
}

试验#2

此解决方案为每个角色的每个用户返回一行,但仅返回RoleId

public class UsersController : Controller {
    public async Task Index() {
        var allUsers = await db.Users.ToListAsync();
        var users = allUsers.Select(u => new UsersViewModel {User = u, Roles = String.Join(",", u.Roles.Select(r => r.RoleId))}).ToList();
        return View(users);
    }
}

以下是我将RoleId更改为RoleName时试用#2的内容: GIF showing objects in User.Roles

我可以说在试验#2中,u.RolesUserRoles表相关联。从逻辑上讲,我知道我想要的是内部加入Roles表并在那里得到名称。

我希望有人可以帮助我吗?提前致谢。 Sample Project

2 个答案:

答案 0 :(得分:1)

感谢@ Kienct89和我们的讨论,我不小心偶然发现了答案。这是我得到的,如果有人能够或想要改进它,请这样做。

例如:我不知道是否最好先将所有角色都放入变量并迭代它,你会在版本1中看到这一点,或者在版本2中看不到。

版本1

var tasks = new Array();
var index = 0;


function addTask() {
    var tempdate = new Date();
    var temptask = document.getElementById("taskinfo").value;
    var td = document.getElementById("taskdate").value;
    tempdate = td + " 00:00";

    tasks[index]["Date"] = tempdate;
    tasks[index]["Task"] = temptask;

    index++

    tasks.sort(function (a, b) { return b.date - a.date });

    var tablecode = "<table class = 'tasktable'>" +
        "<tr>"+
        "<th>Date</th>"+
        "<th>Task</th>"+
        "</tr>";
    for (var i = 0; i < tasks.length; i++) {
        tablecode = tablecode + "<tr>" +
            "<td>" + tasks[i]["Date"].toDateString() + " </td>" +
            "<td>" + tasks[i]["Task"] + " </td>" +
            "</tr>";
    }

    tablecode = tablecode + "</table>";
//I am only returning "temptask" to test with, I will be returning     "tablecode". 
    document.getElementById("bottomright").innerHTML = temptask;

return false;

}

版本2(首选?)

public class UsersController : Controller {
    public async Task Index() {
        var allUsers = await db.Users.ToListAsync();
        var users = allUsers.Select(u => new UsersViewModel {User = u, Roles = String.Join(",", db.Roles.Where(role => role.Users.Any(user => user.UserId == u.Id)).Select(r => r.Name))}).ToList();
        return View(users);
    }
}

我觉得版本2 效率更高,因为它不会命中数据库来获取每个用户的角色。相反,它在变量中具有角色。我不确定自己是不对,但我希望能够开悟并向知道的人学习。

答案 1 :(得分:0)

您不需要在LINQ查询中执行联接,因为 UserRole 只是用户的导航属性(因此它们将自动通过EF映射) 。您唯一需要记住的是,如果禁用延迟加载,则需要手动调用包含(实体)以将实体加载到查询中。

代码示例:

如果您停用&#34;延迟加载&#34;:

public class UsersController : Controller {
    public async Task Index() {
        var users = allUsers.Include(Roles).Select(u => new UserViewModel {UserName = u.UserName, Roles = String.Join(",", u.Roles.Select(r => r.RoleName))}).ToList();
        return View(users);
    }
}

如果您启用&#34;延迟加载&#34;:

public class UsersController : Controller {
    public async Task Index() {
        var users = allUsers.Select(u => new UserViewModel {UserName = u.UserName, Roles = String.Join(",", u.Roles.Select(r => r.RoleName))}).ToList();
        return View(users);
    }
}

<强>更新: 我还没有看过您的模型类,但我认为您有3个模型类(用户,角色,UserRoles),因为用户和角色具有多对多关系(如您所示) gif,角色只有UserId&amp; RoleId)。

public class UsersController : Controller {
    public async Task Index() {
        var users = allUsers.Select(u => new UserViewModel {UserName = u.UserName, Roles = String.Join(",", u.UserRoles.Where(userRole => u.Roles.Select(r => r.RoleId).Contains(userRole.Id)).Select(userRole => userRole.Name)}).ToList();
        return View(users);
    }
}