Sunday, November 6, 2016

How To Change The Names Of The Aspnetuser Tables And How To Stop The Asp.Net Identity Service From Continuing To Create The AspNetUsers Table After Changing The TableNames

I came across something while using the latest version of Asp.Net Identity that will likely save someone out there some time. It was a simple thing, but might not be readily apparent.


By default, when you use the AspNet Identity service, it creates the following set of tables:
  • dbo.AspNetRoles
  • dbo.AspNetUserClaims
  • dbo.AspNetUserLogins
  • dbo.AspNetUserRoles
  • dbo.AspNetUsers
The default schema is dbo and the table names are the default names created by the AspNet Identity service.

To change the default schema, you can do one of a couple of things.
You can add the schema to the OnModelCreating method like so:

  protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
   {
      base.OnModelCreating(modelBuilder);
           
      //your default schema would be a string of your choosing
      modelBuilder.HasDefaultSchema("YourDefaultSchemaHere");
   }

or you can change the schema as you rename the table in the OnModelCreating method

   modelBuilder.Entity<IdentityUser>().ToTable("Users", "YourDefaultSchemaHere");
 

Either of these methods change your tables to:


  • YourDefaultSchemaHere.AspNetRoles
  • YourDefaultSchemaHere.AspNetUserClaims
  • YourDefaultSchemaHere.AspNetUserLogins
  • YourDefaultSchemaHere.AspNetUserRoles
  • YourDefaultSchemaHere.AspNetUsers

  • If you want to change the default AspNet Identity table names, you can do it in the following way:


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

       //this is the default schema that will be used in the system.
       //I have the schema value stored in the app settings area of my web.config 

       modelBuilder.HasDefaultSchema(ConfigurationManager.AppSettings 
       ["DefaultDatabaseSchema"]);

       //the renamed tables

       modelBuilder.Entity<ApplicationUser>().ToTable("Users");

       modelBuilder.Entity<IdentityRole>().ToTable("Roles");

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

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

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



    Using either your new schema name or dbo, you add a field to ApplicationUser like this:


    public class ApplicationUser : IdentityUser
    {
       [Required]
       public string WebsiteUrl { get; set; }


          //...other stuff here
    }


    That field, in this case WebsiteUrl, will be added to the AspNetUsers table.
    That is what you would expect to happen.
    Now, here is where things might get strange for you.
    There is a situation where you can rename the default table and add that field, but the field will NOT be added to the new table name! It will STILL be added to the database, but in the AspNetUsers table! That is NOT what you would expect right? Well here is a little bit of news for you, there is a simple fix for this if this behavior is not what you want.


    If this is happening to you, it is likely happening because you are identifying the IdentityUser table INSTEAD of the ApplicationUser table when you rename your tables.


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


       //this is the default schema that will be used in the system to separate the

       modelBuilder.HasDefaultSchema(ConfigurationManager.AppSettings 
       ["DefaultSchemaToBeUsedToPrefaceCreatedDatabaseTables"]);


       //the renamed tables

       modelBuilder.Entity<ApplicationUser>().ToTable("Users");

       modelBuilder.Entity<IdentityRole>().ToTable("Roles");

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

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

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


    Notice the highlighted field. If you have IdentityUser in that field instead of ApplicationUser, the IdentityUser table and its associated fields will be renamed to Users, however, IdentityUser doesn't know anything about the extra field or fields you might have added in ApplicationUser. ApplicationUser incorporates the IdentityUser fields AND your added field. In my example above, that field is the WebsiteUrl. So, if your system is creating the database tables and STILL creating the AspNetUsers table AFTER you have renamed the table names, check the entity name you are using for the Users table. Remember that it should be ApplicationUser - NOT IdentityUser.


    Smooches!
    Kila