3 votes

Interroger les rôles d'identité EF Core

J'utilise .NET Core 3.1 et je veux interroger les utilisateurs de ma base de données.

J'ai donc modifié mon ApplicationUser comme suit :

public class ApplicationUser : IdentityUser
{
    public ICollection<IdentityUserRole<string>> UserRoles { get; set; }
}

Et maintenant, j'essaie d'interroger les utilisateurs.

var users = from u in DbContext.Users
            select new UserViewModel
            {
                Email = u.Email,
                EmailConfirmed = u.EmailConfirmed,
                Phone = u.PhoneNumber,
                Roles = u.UserRoles.Select(r => r.Role.Name) // Whoops! Won't work
            };

Le problème est que UserRoles ont un RoleId mais ils n'ont pas de propriété Role propriété.

Alors comment puis-je obtenir le nom de ces rôles ?

Mise à jour :

Sur la base des commentaires de Jawad, j'ai modifié mon code comme suit :

public class ApplicationUser : IdentityUser
{
    public ICollection<IdentityRole> Roles { get; set; }
}

Et

Users = (from u in DbContext.Users
         select new UserViewModel
         {
             Email = u.Email,
             EmailConfirmed = u.EmailConfirmed,
             Phone = u.PhoneNumber,
             Roles = u.Roles.Select(r => r.Name)
         })
         .ToList();

Je pensais que je ne pourrais pas le faire parce que c'est une relation de plusieurs à plusieurs. Mais en fait, il compile bien. Cependant, lorsque je l'exécute, j'obtiens une erreur.

Le nom de la colonne 'ApplicationUserId' n'est pas valide.

Je ne suis pas sûr de l'endroit où ce nom de colonne est référencé. Il ne semble pas s'agir d'un nom de colonne dans la base de données.

Mise à jour 2 :

Il s'avère que l'erreur ci-dessus est due à une migration de base de données en cours. Or, je ne voulais pas modifier la base de données. Comme je le soupçonnais initialement, je ne peux pas faire ApplicationUser.ICollection<IdentityRole> parce qu'il y a une table intermédiaire.

J'ai donc réussi à l'exécuter, mais elle n'a renvoyé aucun résultat (parce qu'il n'y a pas de clé étrangère à partir de l'adresse suivante IdentityRole à ApplicationUser .

La question est donc la suivante : comment puis-je interroger les utilisateurs avec leurs rôles ?

2voto

Jonathan Wood Points 26443

Donc, je ne sais pas pourquoi IdentityUserRole ne comprend pas de IdentityRole propriété. Cela semble être une limitation inutile.

Au final, j'ai juste changé ma requête.

var users = await (from u in DbContext.Users
                   join ur in DbContext.UserRoles on u.Id equals ur.UserId
                   join r in DbContext.Roles on ur.RoleId equals r.Id
                   select new
                   {
                       u.Email,
                       u.EmailConfirmed,
                       u.PhoneNumber,
                       Role = r.Name
                   })
                   .ToListAsync();

Users = (from u in users
         group u.Role by u into g
         select new UserViewModel
         {
             Email = g.Key.Email,
             EmailConfirmed = g.Key.EmailConfirmed,
             Phone = g.Key.PhoneNumber,
             Roles = string.Join(", ", g)
         })
         .ToList();

Je n'ai pas pu obtenir le group by pour travailler dans la requête, donc je le groupe après que les données aient été récupérées.

Bref, ça marche.

1voto

Shoejep Points 76

Vous devez créer une nouvelle classe appelée quelque chose comme ApplicationUserRole qui hérite de IdentityUserRole<string> alors il suffit de définir les relations entre ApplicationUser -> ApplicationUserRole y ApplicationRole -> ApplicationUserRole .

modelBuilder.Entity<ApplicationUserRole>(entity =>
{
    entity
      .HasOne(x => x.Role)
      .WithMany(x => x.UserRoles)
      .HasForeignKey(x => x.RoleId);

    entity
      .HasOne(x => x.User)
      .WithMany(x => x.UserRoles)
      .HasForeignKey(x => x.UserId);
 });

Vous devez également remplacer toutes les références aux classes d'identité par vos classes d'application.

public class ApplicationUserRole : IdentityUserRole<string>
{
    public ApplicationUser User { get; set; }

    public ApplicationRole Role { get; set; }
}

public class ApplicationUser : IdentityUser<string>
{
    public ICollection<ApplicationUserRole> UserRoles { get; set; }
}

public class ApplicationRole : IdentityRole<string>
{
    public ICollection<ApplicationUserRole> UserRoles { get; set; }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X