45
votes

I've used ASP.net membership for years and am just starting to try out ASP.net Identity. They just released version 2.0 and which is supposed to support int primary keys. I've defined my custom identity classes as follows in order to get integer primary key support:

public class User : IdentityUser<int, UserLogin, UserRole, UserClaim>
{  
}

public class UserLogin : IdentityUserLogin<int>
{
}

public class Role : IdentityRole<int, UserRole>
{
    public string Description { get; set; }  // Custom description field on roles
}

public class UserRole : IdentityUserRole<int>
{
}

public class UserClaim : IdentityUserClaim<int>
{
}

public class MyDbContext : IdentityDbContext<User, Role, int, UserLogin, UserRole, UserClaim>
{
    public MyDbContext() : this("MyDB") { }

    public MyDbContext(string connStringName) : base(connStringName)
    {
        this.Configuration.LazyLoadingEnabled = false;
        this.Configuration.ProxyCreationEnabled = false;
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {

        modelBuilder.Entity<User>().ToTable("Users");
        modelBuilder.Entity<Role>().ToTable("Roles");
        modelBuilder.Entity<UserRole>().ToTable("UserRoles");
        modelBuilder.Entity<UserLogin>().ToTable("UserLogins");
        modelBuilder.Entity<UserClaim>().ToTable("UserClaims");

        base.OnModelCreating(modelBuilder);
    }
}

When I create a database migration, it properly creates an integer Id column for each of the identity tables, however, it is ignoring my custom table names specified in the OnModelCreating method. Instead I get table names like dbo.AspNetUsers and dbo.AspNetRoles.

I've also tried adding the [Table("TableName")] to my custom identity classes and it has no effect.

In looking at examples for ASP.net Identity 1.0, it looked like they repeated each of the modelBuilder.Entry<Type>().ToTable("TableName") lines using the base Identity classes:

modelBuilder.Entity<User>().ToTable("Users");
modelBuilder.Entity<IdentityUser<int, IdentityUserLogin<int>, IdentityUserRole<int>, IdentityUserClaim<int>>>().ToTable("Users");

modelBuilder.Entity<Role>().ToTable("Roles");
modelBuilder.Entity<IdentityRole<int, UserRole>>().ToTable("Roles");

modelBuilder.Entity<UserRole>().ToTable("UserRoles");
modelBuilder.Entity<IdentityUserRole<int>>().ToTable("UserRoles");

modelBuilder.Entity<UserLogin>().ToTable("UserLogins");
modelBuilder.Entity<IdentityUserLogin<int>>().ToTable("UserLogins");

modelBuilder.Entity<UserClaim>().ToTable("UserClaims");
modelBuilder.Entity<IdentityUserClaim<int>>().ToTable("UserClaims");

However, I tried several variations and my migrations would not generate. I kept receiving errors similar to The type Microsoft.AspNet.Identity.EntityFramework.IdentityUser'4[System.Int32,Microsoft.AspNet.Identity.EntityFramework.IdentityUserLogin'1[System.Int32],Microsoft.AspNet.Identity.EntityFramework.IdentityUserRole'1[System.Int32],Microsoft.AspNet.Identity.EntityFramework.IdentityUserClaim'1[System.Int32]]' was not mapped. Check that the type has not been explicitly excluded by using the Ignore method or NotMappedAttribute data annotation. Verify that the type was defined as a class, is not primitive or generic, and does not inherit from EntityObject.

How can I generate custom table names with integer primary keys in ASP.net Identity 2.0?

2
if you happen to land here looking for identity 3.0, check out this q/a. +1s all arounduser5051310

2 Answers

78
votes

Grrr...... So after wasting a couple hours on this, I copied my rules and pasted them below the base.OnModelCreating(modelBuilder); line and everything worked properly. I didn't realize that the base method needed to be called first :(

Everything is working properly now using the following configuration:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder); // This needs to go before the other rules!

    modelBuilder.Entity<User>().ToTable("Users");
    modelBuilder.Entity<Role>().ToTable("Roles");
    modelBuilder.Entity<UserRole>().ToTable("UserRoles");
    modelBuilder.Entity<UserLogin>().ToTable("UserLogins");
    modelBuilder.Entity<UserClaim>().ToTable("UserClaims");
}
8
votes

In the IdentityModel.cs file, I added the following code to the ApplicationDbContext class

Notice the Model names are different that that names listed in the accepted answer

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<ApplicationUser>().ToTable("SystemUsers");
        modelBuilder.Entity<IdentityRole>().ToTable("SystemRoles");
        modelBuilder.Entity<IdentityUserRole>().ToTable("SystemUserRoles");
        modelBuilder.Entity<IdentityUserLogin>().ToTable("SystemUserLogins");
        modelBuilder.Entity<IdentityUserClaim>().ToTable("SystemUserClaims");
    }