ユーザー管理管理ページのすべてのIDユーザーとそれらに関連付けられたロールを引き出しようとしています。これはかなり簡単だが、明らかにそうではないと思った。私は次の解決策を試してみました: https://stackoverflow.com/a/43562544/5392786 しかし、それは今のところうまくいきませんでした。
ここに私がこれまで持っているものがあります:
ApplicationUser:
_public class ApplicationUser : IdentityUser
{
public List<IdentityUserRole<string>> Roles { get; set; }
}
_
DBContext
_public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
}
_
スタートアップIDコード
_services.AddIdentity<ApplicationUser, IdentityRole>(options => options.Stores.MaxLengthForKeys = 128)
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
_
リストを表示したいRazorページ:
_public class IndexModel : PageModel
{
private readonly UserManager<ApplicationUser> userManager;
public IndexModel(UserManager<ApplicationUser> userManager)
{
this.userManager = userManager;
}
public IEnumerable<ApplicationUser> Users { get; set; }
public void OnGetAsync()
{
this.Users = 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のこの comment/issue は、.Net Coreの現在のソリューションのようです。私は次のコードでそれを実装しようとしました:
ApplicationUser
_public class ApplicationUser : IdentityUser
{
public ICollection<ApplicationUserRole> UserRoles { get; set; }
}
_
ApplicationUserRole
_public class ApplicationUserRole : IdentityUserRole<string>
{
public virtual ApplicationUser User { get; set; }
public virtual ApplicationRole Role { get; set; }
}
_
ApplicationRole
_public class ApplicationRole : IdentityRole
{
public ICollection<ApplicationUserRole> UserRoles { get; set; }
}
_
DBContext
_public class ApplicationDbContext
: IdentityDbContext<ApplicationUser, ApplicationRole, string, IdentityUserClaim<string>,
ApplicationUserRole, IdentityUserLogin<string>,
IdentityRoleClaim<string>, IdentityUserToken<string>>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<ApplicationUserRole>(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<ApplicationUser, ApplicationRole>(options => options.Stores.MaxLengthForKeys = 128)
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
_
最後に、それを使用しているときは、ユーザーのUserRolesを熱心にロードしてから、UserRoleのロールを次のようにロードしてください。
_this.Users = userManager.Users.Include(u => u.UserRoles).ThenInclude(ur => ur.Role).ToList();
_
各Role
のUserRole
プロパティがnullであるという問題があり、これは.ThenInclude(ur => ur.Role)
部分を追加することで解決しました。
マルチレベルの積極的な読み込みに関するMicrosoftドキュメント: https://docs.Microsoft.com/en-us/ef/core/querying/related-data#include-multiple-levels
ユーザーリストをループし、_userManager.GetRolesAsync(user)関数を呼び出してユーザーロールを取得し、ユーザーのロールをループし、1つの文字列変数で「、」を使用してロールを分割します
[HttpPost]
public async Task<IActionResult> OnPostGetPagination()
{
var users = await _userManager.Users.ToListAsync();
InputModel inputModel = new InputModel();
foreach (var v in users)
{
inputModel = new InputModel();
var roles = await _userManager.GetRolesAsync(v);
inputModel.Email = v.UserName;
inputModel.role = "";
foreach (var r in roles)
{
if (!inputModel.role.Contains(","))
{
inputModel.role = r;
}
else
{
inputModel.role = "," + r;
}
}
Input2.Add(inputModel);
}
}
がんばろう
参照 コメント
最初はデータを取得するコードです
public async Task<IEnumerable<AccountViewModel>> 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<IdentityUserRole<string>> Users { get; set; }
public virtual ICollection<IdentityRoleClaim<string>> 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<User>().HasMany(u => u.Claims).WithOne().HasForeignKey(c => c.UserId).IsRequired().OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<User>().HasMany(u => u.Roles).WithOne().HasForeignKey(r => r.UserId).IsRequired().OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<ApplicationRole>().HasMany(r => r.Claims).WithOne().HasForeignKey(c => c.RoleId).IsRequired().OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<ApplicationRole>().HasMany(r => r.Users).WithOne().HasForeignKey(r => r.RoleId).IsRequired().OnDelete(DeleteBehavior.Cascade);
modelBuilder.EnableAutoHistory(null);
}
結果は、ユーザー名とユーザーロールになります。ユーザーが複数のロールを持っている場合、データはこの管理者、編集者などのように表示されます...