Quiero obtener todos los usuarios con sus roles agrupados por su nombre, y también incluir a los usuarios que no tienen ningún rol.

Estoy usando asp.net identidad 2 hasta ahora he intentado

from user in users
from identityUserRole in user.Roles
join identityRole in identityRole on identityUserRole.RoleId equals identityRole.Id into r
from roles in r
group roles.Name by user.UserName into g
select new
{
    UserName = g.Key,
    Roles = g.ToList()
};

Pero esto solo devuelve usuarios que tienen un rol.

2
Producenta 20 jun. 2017 a las 12:40

3 respuestas

La mejor respuesta

Prefiero usar un modelo para mapear datos:

public class UserDto
{
    public string UserName { set; get; }
    public List<string> Roles { set; get; }
}

Y luego obtener todos los usuarios y sus nombres de roles como este:

var users = (from u in db.Users
             let query = (from ur in db.Set<IdentityUserRole>()
                          where ur.UserId.Equals(u.Id)
                          join r in db.Roles on ur.RoleId equals r.Id
                          select r.Name)
             select new UserDto { UserName = u.UserName, Roles = query.ToList() })
             .ToList();
2
tmg 20 jun. 2017 a las 10:31

También podría simplificar su consulta a esto.

var userAndRoles = users.Select(user => new
{
    UserName = user.UserName,
    Roles = roles.Where(role => user.Roles.Any(userRole => userRole.UserId == user.UserId && userRole.RoleId == role.RoleId))
});
1
NtFreX 20 jun. 2017 a las 11:14

Para realizar una "unión izquierda" con listas de roles vacías, intente:

from roles in r.DefaultIfEmpty()
1
Chrille 20 jun. 2017 a las 09:47