1

I am extending IdentityUserRole to have another primary key / foreign key Id field called WorkspaceId.

I am getting this error: "'ApplicationUserRole' cannot have KeyAttribute on property 'WorkspaceId' since primary key can only be declared on the root type"

Here is my ApplicationUserRole class:

public partial class ApplicationUserRole: IdentityUserRole<string>
{

    [Key, ForeignKey("WorkspaceId")]
    public string WorkspaceId { get; set; }

    public virtual Workspace Workspace { get; set; }
}

In DbContext I'm doing:

 modelBuilder.Entity<ApplicationUserRole>(entity =>
            {
                entity.HasKey(k => new { k.RoleId, k.WorkspaceId, k.UserId });
                entity.HasOne(r => r.Workspace).WithMany();
            });

What is the best way to add a primary key to my UserRoles table, or, is it better and safer to just create another table? It just seems a bit overkill to me to have another table that includes both PKs/FKs from IdentityUserRole and the WorkspaceId PK/FK. This would mean I'd need to maintain both tables.

Also, I'm using .net Core 1.1

Update 1

Upon reviewing and implementing the findings: here and here

I am getting the following error when migrating:

'Models.ApplicationUser', on 'Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore`4[TUser,TRole,TContext,TKey]' violates the constraint of type 'TUser'

Here is my Application User

 public class ApplicationUser : IdentityUser<string, ApplicationUserClaim, ApplicationUserRole, ApplicationUserLogin>

Here is my User Store:

 public class ApplicationUserStore : UserStore<ApplicationUser, ApplicationRole, ApplicationDbContext, string, ApplicationUserClaim, ApplicationUserRole, ApplicationUserLogin, ApplicationUserToken, ApplicationRoleClaim>

Here is my code in Startup:

services.AddIdentity<ApplicationUser, ApplicationRole>()
            .AddEntityFrameworkStores<ApplicationDbContext, string>()
            .AddDefaultTokenProviders()
            .AddUserStore<ApplicationUserStore>()
            .AddRoleStore<ApplicationRoleStore>();



services.AddScoped<UserStore<ApplicationUser, ApplicationRole, AsherDbContext, string, ApplicationUserClaim, ApplicationUserRole, ApplicationUserLogin, ApplicationUserToken, ApplicationRoleClaim>, ApplicationUserStore>();           
        services.AddScoped<RoleManager<ApplicationRole>>();
        services.AddScoped<SignInManager<ApplicationUser>>();

Here are my Identity Models:

public class ApplicationUserRole : IdentityUserRole<string>
public class ApplicationUserClaim : IdentityUserClaim<string>
public class ApplicationUserLogin : IdentityUserLogin<string>
public class ApplicationRoleClaim : IdentityRoleClaim<string> 
public class ApplicationUserToken : IdentityUserToken<string>
public class ApplicationRole : IdentityRole<string, ApplicationUserRole, ApplicationRoleClaim>

Update 2 Removing the following line fixed the constraint violation error:

.AddEntityFrameworkStores<AsherDbContext, string>()
Eric
  • 7,930
  • 17
  • 96
  • 128

1 Answers1

2

ApplicationUserRole derives from IdentityUserRole that is already included in the model, so the key needs to be configured on it, as it's the base class. By default IdentityDbContext configures its key as {UserId, RoleId}.

Same kind of question has been answered here:

Customised IdentityUserRole primary key

mukesh joshi
  • 584
  • 5
  • 19