身份 2.2.1 中具有角色列表的用户列表
List of Users with list of Roles in Identity 2.2.1
所以我一直在搜索 Google 等等。感觉这个问题已经被问过很多次了,但没有答案对我有帮助,但我觉得我已经接近了。但是,我是 LINQ 和 Lambda 的新手,不具备做我想做的事情的知识。
想要的结果
User Roles
-----------------------------------------
John Admin
Jane Staff, HR, Payroll
MyCoolUserName User
我离 and this post 很近了。这是我到目前为止得到的。
视图模型:
public class UsersViewModel {
[Display(Name = "User")]
public ApplicationUser User { get; set; }
[Display(Name = "Roles")]
public string Roles { get; set; }
}
控制器:
试验#1
此解决方案 returns 角色空白,我必须将其添加到我的 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
此解决方案 returns 每个用户每个角色一行,但只有 returns 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 中得到的结果:
我可以看出在试验 #2 中,u.Roles
链接到 UserRoles
table。从逻辑上讲,我知道我想要的是内部加入 Roles
table 并在那里获取名称。
我希望有人能帮助我吗?提前致谢。 Sample Project
您不需要在 LINQ 查询中执行联接,因为 UserRole 只是 User 的 导航 属性 (因此它们将由 EF 自动映射)。唯一需要记住的是,如果禁用延迟加载,则需要手动调用 Include(entity) 将实体加载到查询中。
代码示例:
如果您禁用 "Lazy Loading":
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);
}
}
如果您启用 "Lazy Loading":
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 个模型 类(用户、角色、用户角色),因为用户和角色具有 多对多关系(如您的 gif 所示,角色只有 UserId 和 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);
}
}
感谢@Kienct89 和我们的讨论,我自己偶然发现了答案。这是我得到的,如果有人可以或想要改进它,请这样做。
例如:我不知道首先将所有角色放入一个变量并对其进行迭代是否更好,您在版本 1 中看到了这一点,或者在版本 2 中看到了这一点。
版本 1
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(首选?)
public class UsersController : Controller {
public async Task Index() {
var allUsers = await db.Users.ToListAsync();
// set all roles to a variable, so that we don't hit the database for every user iteration
// is this true?
var allRoles = await db.Roles.ToListAsync();
var users = allUsers.Select(u => new UsersViewModel {User = u, Roles = String.Join(",", allRoles.Where(role => role.Users.Any(user => user.UserId == u.Id)).Select(r => r.Name))}).ToList();
return View(users);
}
}
我觉得 版本 2 效率更高,因为它不会访问数据库来获取每个用户的角色。相反,它具有变量中的角色。我不确定我是否正确,但我想得到启发并向任何知道的人学习。
所以我一直在搜索 Google 等等。感觉这个问题已经被问过很多次了,但没有答案对我有帮助,但我觉得我已经接近了。但是,我是 LINQ 和 Lambda 的新手,不具备做我想做的事情的知识。
想要的结果
User Roles
-----------------------------------------
John Admin
Jane Staff, HR, Payroll
MyCoolUserName User
我离
视图模型:
public class UsersViewModel {
[Display(Name = "User")]
public ApplicationUser User { get; set; }
[Display(Name = "Roles")]
public string Roles { get; set; }
}
控制器:
试验#1
此解决方案 returns 角色空白,我必须将其添加到我的 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
此解决方案 returns 每个用户每个角色一行,但只有 returns 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 中得到的结果:
我可以看出在试验 #2 中,u.Roles
链接到 UserRoles
table。从逻辑上讲,我知道我想要的是内部加入 Roles
table 并在那里获取名称。
我希望有人能帮助我吗?提前致谢。 Sample Project
您不需要在 LINQ 查询中执行联接,因为 UserRole 只是 User 的 导航 属性 (因此它们将由 EF 自动映射)。唯一需要记住的是,如果禁用延迟加载,则需要手动调用 Include(entity) 将实体加载到查询中。
代码示例:
如果您禁用 "Lazy Loading":
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);
}
}
如果您启用 "Lazy Loading":
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 个模型 类(用户、角色、用户角色),因为用户和角色具有 多对多关系(如您的 gif 所示,角色只有 UserId 和 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);
}
}
感谢@Kienct89 和我们的讨论,我自己偶然发现了答案。这是我得到的,如果有人可以或想要改进它,请这样做。
例如:我不知道首先将所有角色放入一个变量并对其进行迭代是否更好,您在版本 1 中看到了这一点,或者在版本 2 中看到了这一点。
版本 1
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(首选?)
public class UsersController : Controller {
public async Task Index() {
var allUsers = await db.Users.ToListAsync();
// set all roles to a variable, so that we don't hit the database for every user iteration
// is this true?
var allRoles = await db.Roles.ToListAsync();
var users = allUsers.Select(u => new UsersViewModel {User = u, Roles = String.Join(",", allRoles.Where(role => role.Users.Any(user => user.UserId == u.Id)).Select(r => r.Name))}).ToList();
return View(users);
}
}
我觉得 版本 2 效率更高,因为它不会访问数据库来获取每个用户的角色。相反,它具有变量中的角色。我不确定我是否正确,但我想得到启发并向任何知道的人学习。