简体   繁体   中英

.NET Core how to override/extend IdentityUserRole and IdentityUserClaim

I am trying to replace the default IdentityUserRole class with my own called UserRoles. What I have done so far:

[Table("IdentityUserRole", Schema = "ManagementStudio")]
public class UserRoles : IdentityUserRole<string>
{
    [Key]
    public string Id { get; set; }
    [ForeignKey("Users")]
    public override string UserId { get; set; }
    public virtual ApplicationUsers Users { get; set; }
    [ForeignKey("Roles")]
    public override string RoleId { get; set; }
    public virtual Roles Roles { get; set; }
}

In my DbContext class:

public DbSet<UserRoles> UserRoles{ get; set; }

In my onModelBuilding

modelBuilder.Entity<UserRoles>()
            .ToTable("IdentityUserRole", schema: "ManagementStudio");

This is the error I get when I try to login:

An unhandled exception occurred while processing the request. InvalidOperationException: Cannot create a DbSet for 'IdentityUserRole' because this type is not included in the model for the context. Microsoft.EntityFrameworkCore.Internal.InternalDbSet.get_EntityType()

This happens for IdentityUserClaim as well.

You should specify the new model UserRole when inheriting IdentityDbContext on your DbContext class.

Like this.

public class ApplicationDbContext : IdentityDbContext<User, Role, Guid, IdentityUserClaim<Guid>, UserRole , IdentityUserLogin<Guid>, IdentityRoleClaim<Guid>, IdentityUserToken<Guid>>
{
    ...
}

as you can see, I replaced IdentityUserRole with UserRole since I want to override it.

if you look into the definition of IdentityUserRole, you'll find out that it already has primary keys

public class IdentityUserRole<TKey> where TKey : IEquatable<TKey>
{
    public IdentityUserRole();

    //
    // Summary:
    //     Gets or sets the primary key of the user that is linked to a role.
    public virtual TKey UserId { get; set; }
    //
    // Summary:
    //     Gets or sets the primary key of the role that is linked to the user.
    public virtual TKey RoleId { get; set; }
}

we have to override the user role implementation. Now if you see the code, you'll see that we can override it. So I did this:

 public class MyDbContext : IdentityDbContext<
    User,
    Role,
    string,
    IdentityUserClaim<string>,
    UserRole,
    IdentityUserLogin<string>,
    IdentityRoleClaim<string>,
    IdentityUserToken<string>>

//And this is to override primary keys in UserRole:

 protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);
    modelBuilder.Entity<UserRole>(userRole =>
    {
        userRole.HasKey(pr => new
        {
            pr.UserId,
            pr.RoleId,
            pr.ClientId
        });
    }
}

After we override the database context, we can use custom TUserRole, for example like this one:

   public class UserRole : IdentityUserRole<string>
{
    [Required, StringLength(36)]
    public string ClientId { get; set; }
    [ForeignKey("ClientId")]
    public virtual Client Client { get; set; }
    public virtual User User { get; set; }
    public virtual Role Role { get; set; }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM