.NET Core 2.1 Identity为所有用户提供相关角色

我正在尝试为用户管理管理页面提取所有Identity用户及其相关角色。 我认为这将相当容易,但显然不是。 我尝试过以下解决方案: https : //stackoverflow.com/a/43562544/5392786但到目前为止还没有解决。

这是我到目前为止:

ApplicationUser:

public class ApplicationUser : IdentityUser { public List<IdentityUserRole> Roles { get; set; } } 

的DbContext

 public class ApplicationDbContext : IdentityDbContext { public ApplicationDbContext(DbContextOptions options) : base(options) { } } 

启动标识代码

 services.AddIdentity(options => options.Stores.MaxLengthForKeys = 128) .AddEntityFrameworkStores() .AddDefaultTokenProviders(); 

我要显示列表的Razor页面:

 public class IndexModel : PageModel { private readonly UserManager userManager; public IndexModel(UserManager userManager) { this.userManager = userManager; } public IEnumerable Users { get; set; } public void OnGetAsync() { this.Users = userManager.Users.Include(u => u.Roles).ToList(); } } 

调用userManager.Users.Include(u => u.Roles).ToList();时,我收到以下错误userManager.Users.Include(u => u.Roles).ToList();

MySql.Data.MySqlClient.MySqlException:’字段列表’中的’未知列’u.Roles.ApplicationUserId’

我现在已经实现了以下解决方案。

正如CodeNotFound在评论中指出的那样,IdentityUser曾经拥有一个Roles属性。 在.NET Core中不再是这种情况。 GitHub上的这个评论/问题似乎是.Net Core的当前解决方案。 我试图用以下代码实现它:

ApplicationUser

 public class ApplicationUser : IdentityUser { public ICollection UserRoles { get; set; } } 

ApplicationUserRole

 public class ApplicationUserRole : IdentityUserRole { public virtual ApplicationUser User { get; set; } public virtual ApplicationRole Role { get; set; } } 

ApplicationRole

 public class ApplicationRole : IdentityRole { public ICollection UserRoles { get; set; } } 

的DbContext

 public class ApplicationDbContext : IdentityDbContext, ApplicationUserRole, IdentityUserLogin, IdentityRoleClaim, IdentityUserToken> { public ApplicationDbContext(DbContextOptions options) : base(options) { } protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); builder.Entity(userRole => { userRole.HasKey(ur => new { ur.UserId, ur.RoleId }); userRole.HasOne(ur => ur.Role) .WithMany(r => r.UserRoles) .HasForeignKey(ur => ur.RoleId) .IsRequired(); userRole.HasOne(ur => ur.User) .WithMany(r => r.UserRoles) .HasForeignKey(ur => ur.UserId) .IsRequired(); }); } } 

启动

 services.AddIdentity(options => options.Stores.MaxLengthForKeys = 128) .AddEntityFrameworkStores() .AddDefaultTokenProviders(); 

最后,确保在使用它时,您急切地加载用户的UserRoles,然后是UserRole的角色,如下所示:

 this.Users = userManager.Users.Include(u => u.UserRoles).ThenInclude(ur => ur.Role).ToList(); 

我有一个问题,其中每个UserRoleRole属性为null,这是通过添加.ThenInclude(ur => ur.Role)部分来解决的。

Microsoft doc on multi-level eager loading: https : //docs.microsoft.com/en-us/ef/core/querying/related-data#including-multiple-levels

参考评论

首先是获取数据的代码

  public async Task> GetUserList() { var userList = await (from user in _context.Users select new { UserId = user.Id, Username = user.UserName, user.Email, user.EmailConfirmed, RoleNames = (from userRole in user.Roles //[AspNetUserRoles] join role in _context.Roles //[AspNetRoles]// on userRole.RoleId equals role.Id select role.Name).ToList() }).ToListAsync(); var userListVm = userList.Select(p => new AccountViewModel { UserId = p.UserId, UserName = p.Username, Email = p.Email, Roles = string.Join(",", p.RoleNames), EmailConfirmed = p.EmailConfirmed.ToString() }); return userListVm; } 

在ASP.Net核心2.1中,我们像这样设置ApplicationRole以获得用户的角色。 您需要定义要显式公开的数据以供用户使用

 public class ApplicationRole : IdentityRole { public virtual ICollection> Users { get; set; } public virtual ICollection> Claims { get; set; } } 

最后

 protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); foreach (var relationship in modelBuilder.Model.GetEntityTypes().SelectMany(e => e.GetForeignKeys())) { relationship.DeleteBehavior = DeleteBehavior.Restrict; } modelBuilder.Entity().HasMany(u => u.Claims).WithOne().HasForeignKey(c => c.UserId).IsRequired().OnDelete(DeleteBehavior.Cascade); modelBuilder.Entity().HasMany(u => u.Roles).WithOne().HasForeignKey(r => r.UserId).IsRequired().OnDelete(DeleteBehavior.Cascade); modelBuilder.Entity().HasMany(r => r.Claims).WithOne().HasForeignKey(c => c.RoleId).IsRequired().OnDelete(DeleteBehavior.Cascade); modelBuilder.Entity().HasMany(r => r.Users).WithOne().HasForeignKey(r => r.RoleId).IsRequired().OnDelete(DeleteBehavior.Cascade); modelBuilder.EnableAutoHistory(null); } 

结果将是用户名和用户角色。 如果用户拥有多个角色,则数据将显示为此管理员,编辑器等…

完整的代码可以在这里找到 这里和这里希望这个帮助。