Multiple user type Identity - DbContext design
I reproduced your problem and below is a solution to it, but I would think again about creating multiple tables for different user roles.
Here are two main reasons against multiple user tables:
- When you want to find the user by id (Assuming you don't know the role), you will need to run multiple queries against different tables, which decreases performance and increases complexity in code.
- It may also increase database complexity, because you will need to set multiple foreign keys to other tables.
In case you still want to have multiple tables for different user roles, here is a little "hack". You just need to override OnModelCreating method and configure entities:
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<Contractor>(b =>
{
b.HasMany<IdentityUserRole<Guid>>().WithOne().HasForeignKey(ur => ur.UserId).IsRequired();
});
builder.Entity<UserRole>(b =>
{
b.HasKey(r => r.Id);
b.HasIndex(r => r.NormalizedName).HasName("RoleNameIndex").IsUnique();
b.ToTable("AspNetRoles");
b.Property(r => r.ConcurrencyStamp).IsConcurrencyToken();
b.Property(u => u.Name).HasMaxLength(256);
b.Property(u => u.NormalizedName).HasMaxLength(256);
b.HasMany<IdentityUserRole<Guid>>().WithOne().HasForeignKey(ur => ur.RoleId).IsRequired();
b.HasMany<IdentityRoleClaim<Guid>>().WithOne().HasForeignKey(rc => rc.RoleId).IsRequired();
});
builder.Entity<IdentityRoleClaim<Guid>>(b =>
{
b.HasKey(rc => rc.Id);
b.ToTable("AspNetRoleClaims");
});
builder.Entity<IdentityUserRole<Guid>>(b =>
{
b.HasKey(r => new { r.UserId, r.RoleId });
b.ToTable("AspNetUserRoles");
});
builder.Entity<UserRole>().ToTable("Roles");
builder.Entity<IdentityUserRole<Guid>>().ToTable("UserRoles");
builder.Entity<IdentityRoleClaim<Guid>>().ToTable("RoleClaims");
builder.Entity<IdentityUserClaim<Guid>>().ToTable("UserClaims");
}
After that, you should be able to login.