Search code examples
c#.netasp.net-identity

.net Identity: error trying to change string (GUID?) keys to int


I have an application (using Identity 2.2) created in VS2015 with the example application (MVC, mvc individual authentication), which I modified following a tutorial to add some custom fields to the users table (using a migration to get added fields into the database). Then for the rest of the tables (non-Identity ones) I am using EntityFramework database-first to generate CRUD controllers & views etc. So far so good, everything seems to be working nicely.

Now I am trying to modify it so that the keys for Identity tables are integers instead of GUIDs. I have followed this tutorial (with MVC update 3), https://learn.microsoft.com/en-us/aspnet/identity/overview/extensibility/change-primary-key-for-users-in-aspnet-identity#context

but after following the tutorial, when I build and run the solution I get this error when it tries to generate the models

One or more validation errors were detected during model generation: Proyecto.Models.IdentityUserRole: : EntityType 'IdentityUserRole' has no key defined. Define the key for this EntityType.
IdentityUserRoles: EntityType: EntitySet 'IdentityUserRoles' is based on type 'IdentityUserRole' that has no keys defined.

I have no idea how to fix it... any help is appreciated.

my Models/IdentityModels.cs:

public class ApplicationUser : IdentityUser<int, CustomUserLogin, CustomUserRole, CustomUserClaim>

{
    //added custom fields
    [Column(TypeName = "varchar")]
    [StringLength(50)]
    public string Nombre { get; set; }
    public DateTime FechaAlta { get; set; }
    public DateTime? FechaUltModif { get; set; }
    public bool Activo { get; set; }
    public string Notas { get; set; }

    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser, int> manager)
    {
        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        // Add custom user claims here
        return userIdentity;
    }
}

public class ApplicationDbContext : IdentityDbContext<ApplicationUser, CustomRole, int, CustomUserLogin, CustomUserRole, CustomUserClaim>
{
    public ApplicationDbContext()
        : base("DefaultConnection")
    {
    }

    public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext();
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        //to fix some conflicts using mysql
        modelBuilder.Entity<ApplicationUser>().Property(u => u.UserName).HasMaxLength(255);
        modelBuilder.Entity<ApplicationUser>().Property(u => u.Email).HasMaxLength(255);
        modelBuilder.Entity<IdentityRole>().Property(r => r.Name).HasMaxLength(255);
    }

}


//aded for int keys
public class CustomUserRole : IdentityUserRole<int> { }
public class CustomUserClaim : IdentityUserClaim<int> { }
public class CustomUserLogin : IdentityUserLogin<int> { }
public class CustomRole : IdentityRole<int, CustomUserRole>
{
    public CustomRole() { }
    public CustomRole(string name) { Name = name; }
}
public class CustomUserStore : UserStore<ApplicationUser, CustomRole, int,
    CustomUserLogin, CustomUserRole, CustomUserClaim>
{
    public CustomUserStore(ApplicationDbContext context)
        : base(context)
    {
    }
}
public class CustomRoleStore : RoleStore<CustomRole, int, CustomUserRole>
{
    public CustomRoleStore(ApplicationDbContext context)
        : base(context)
    {
    }
}

Solution

  • Here is your problem:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
           //your problem is in this line change IdentityRole  to CustomRole 
            modelBuilder.Entity<IdentityRole>().Property(r => r.Name).HasMaxLength(255);
        }
    

    use CustomRole instead of IdentityRole because IdentityRole defined with string primary key and in CustomUserRole you are using int

    if you go to definition of IdentityRole you will find its extended IdentityRole<string, IdentityUserRole> and its why you are getting error

    Currected Code:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        //to fix some conflicts using mysql
        modelBuilder.Entity<ApplicationUser>().Property(u => u.UserName).HasMaxLength(255);
        modelBuilder.Entity<ApplicationUser>().Property(u => u.Email).HasMaxLength(255);
        modelBuilder.Entity<CustomRole>().Property(r => r.Name).HasMaxLength(255);
    }