238

I am using the release version (RTM, not RC) of Visual Studio 2013 (downloaded from MSDN 2013-10-18) and therefore the latest (RTM) version of AspNet.Identity. When I create a new web project, I select "Individual User Accounts" for authentication. This creates the following tables:

  1. AspNetRoles
  2. AspNetUserClaims
  3. AspNetUserLogins
  4. AspNetUserRoles
  5. AspNetUsers

When I register a new user (using the default template), these tables (listed above) are created and the AspNetUsers table has a record inserted which contains:

  1. Id
  2. UserName
  3. PasswordHash
  4. SecurityStamp
  5. Discriminator

Additionally, by adding public properties to the class "ApplicationUser" I have successfully added additional fields to the AspNetUsers table, such as "FirstName", "LastName", "PhoneNumber", etc.

Here's my question. Is there a way to change the names of the above tables (when they are first created) or will they always be named with the AspNet prefix as I listed above? If the table names can be named differently, please explain how.

-- UPDATE --

I implemented @Hao Kung's solution. It does create a new table (for example I called it MyUsers), but it also still creates the AspNetUsers table. The goal is to replace the "AspNetUsers" table with the "MyUsers" table. See code below and database image of tables created.

I would actually like to replace each AspNet table with my own name... For fxample, MyRoles, MyUserClaims, MyUserLogins, MyUserRoles, and MyUsers.

How do I accomplish this and end up with only one set of tables?

public class ApplicationUser : IdentityUser
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string PostalCode { get; set; }
    public string PhonePrimary { get; set; }
    public string PhoneSecondary { get; set; }
}

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext(): base("DefaultConnection")
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Entity<IdentityUser>().ToTable("MyUsers");
    }
}

Database Tables

-- UPDATE ANSWER --

Thanks to both Hao Kung and Peter Stulinski. This solved my problem...

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

        modelBuilder.Entity<IdentityUser>().ToTable("MyUsers").Property(p => p.Id).HasColumnName("UserId");
        modelBuilder.Entity<ApplicationUser>().ToTable("MyUsers").Property(p => p.Id).HasColumnName("UserId");
        modelBuilder.Entity<IdentityUserRole>().ToTable("MyUserRoles");
        modelBuilder.Entity<IdentityUserLogin>().ToTable("MyUserLogins");
        modelBuilder.Entity<IdentityUserClaim>().ToTable("MyUserClaims");
        modelBuilder.Entity<IdentityRole>().ToTable("MyRoles");
    }
Erik Philips
  • 53,428
  • 11
  • 128
  • 150
user2315985
  • 2,848
  • 5
  • 17
  • 18
  • Are you sure? Please delete all your tables, remove your _migration table and then try. The code i have posted below which is very similar to yours does not create the AspNetUsers table. – Piotr Stulinski Oct 29 '13 at 16:45
  • To make sure, I deleted the entire database, even created a new c# web project in Visual Studio. It creates all the AspNet tables and also the MyUsers table (as pictured above). It creates the _MigrationHistory table and there is one record inserted with a MigrationId: "201310292106426_InitialCreate" – user2315985 Oct 29 '13 at 21:10
  • 1
    The only difference between your code and mine is that i renamed ApplicationUser to "User". My behavior is quite different. On first create it creates the tables as needed and with the names i specify.... Maybe just for "experimentation" sake try change ApplicationUser to User and then add the lines base.OnModelCreating(modelBuilder); modelBuilder.Entity() .ToTable("Users", "dbo"); modelBuilder.Entity() .ToTable("Users", "dbo"); – Piotr Stulinski Oct 30 '13 at 16:29
  • 1
    Updated solution above... – user2315985 Oct 30 '13 at 21:25
  • do you know how to remove the discriminator columns? – Jaime Sangcap Sep 25 '14 at 08:52
  • 6
    @Daskul Remove modelBuilder.Entity().ToTable("MyUsers").Property(p => p.Id).HasColumnName("UserId"); and in that case discriminator column will not be added to MyUsers table. See this error for more info: http://stackoverflow.com/questions/22054168/duplicate-foreign-keys-when-renaming-asp-net-identity-tables – Sergey Nov 13 '14 at 15:09
  • [see here](http://stackoverflow.com/questions/22855428/how-to-change-table-names-for-asp-net-identity-2-0-with-int-id-columns) to save you some googling around. this question + that one made it click –  Aug 13 '16 at 06:05
  • 1
    @user2315985 - You should update your answer to remove the line containing `modelBuilder.Entity().ToTable("MyUsers").Property(p => p.Id).HasColumnName("UserId");` as mentioned by @Sergey. Otherwise, the newly named `MyUsers` table has a discriminator column as @Daskul pointed out. Also, your `MyUserClaims` table structure will be wrong as @Matt Overall pointed out. I think the idea to add that came from a comment to @Giang in a [msdn blog](https://blogs.msdn.microsoft.com/webdev/2013/10/16/customizing-profile-information-in-asp-net-identity-in-vs-2013-templates/), but its wrong! – kimbaudi Oct 13 '16 at 06:52
  • For `.NET 6`, check the first part of this answer: https://stackoverflow.com/a/74856286/8644294 – Ash K Dec 19 '22 at 21:43

10 Answers10

136

You can do this easily by modifying the IdentityModel.cs as per the below:

Override OnModelCreating in your DbContext then add the following, this will change AspNetUser table to "Users" you can also change the field names the default Id column will become User_Id.

modelBuilder.Entity<IdentityUser>()
                    .ToTable("Users", "dbo").Property(p => p.Id).HasColumnName("User_Id");

or simply the below if you want to keep all the standard column names:

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

Full example below (this should be in your IdentityModel.cs file) i changed my ApplicationUser class to be called User.

public class User : IdentityUser
    {
        public string PasswordOld { get; set; }
        public DateTime DateCreated { get; set; }

        public bool Activated { get; set; }

        public bool UserRole { get; set; }

    }

public class ApplicationDbContext : IdentityDbContext<User>
    {
        public ApplicationDbContext()
            : base("DefaultConnection")
        {
        }

        protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Entity<IdentityUser>()
                .ToTable("Users", "dbo").Property(p => p.Id).HasColumnName("User_Id");
            modelBuilder.Entity<User>()
                .ToTable("Users", "dbo").Property(p => p.Id).HasColumnName("User_Id");
        }
    }

Please note i have not managed to get this working if the current table exists. Also note whatever columns you do not map the default ones will be created.

starball
  • 20,030
  • 7
  • 43
  • 238
Piotr Stulinski
  • 9,241
  • 8
  • 31
  • 46
  • 3
    To get these changes to come into an effect you need to use migrations to push the changes to the existing database. – Lukasz Feb 19 '14 at 19:52
  • 2
    If you do this, your foreign keys will be a little odd, I don't think you are required to change the table name on IdentityUser. See this [SO post](https://stackoverflow.com/questions/22054168/duplicate-foreign-keys-when-renaming-asp-net-identity-tables/23041949#23041949) – Matt Overall Sep 05 '15 at 22:22
  • 1
    Just as an extra check as this caught me out previously. Make sure the call to `base.OnModelCreating` is the first line of code in the override otherwise the rest of the lines are overwritten by the base Identity class. – DavidG Jan 22 '16 at 09:34
  • @DavidG Thank you indeed – S.A. Jul 10 '16 at 17:30
  • Good solution. But it's not necessary to overwrite the table name for IdentityUser. See this solution http://stackoverflow.com/questions/28016684/identity-2-0-code-first-table-renaming – EJW Apr 11 '17 at 09:55
  • I think this was version 1.0 (initial release) – Piotr Stulinski Apr 11 '17 at 17:48
  • Note that if you have a derived class (custom role) from IdentityRole, for example, you must indicate that you use the same table for both entities: base class role, and the derived role.`modelBuilder.Entity().ToTable("UserRoles");` and `modelBuilder.Entity().ToTable("UserRoles");` – MSD561 Jan 31 '19 at 18:57
71

Below is my working solution:

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext()
        : base("DefaultConnection", throwIfV1Schema: false)
    {
    }

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

        modelBuilder.Entity<ApplicationUser>().ToTable("User");
        modelBuilder.Entity<IdentityRole>().ToTable("Role");
        modelBuilder.Entity<IdentityUserRole>().ToTable("UserRole");
        modelBuilder.Entity<IdentityUserClaim>().ToTable("UserClaim");
        modelBuilder.Entity<IdentityUserLogin>().ToTable("UserLogin");
    }

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

See this for more detail

DavidG
  • 113,891
  • 12
  • 217
  • 223
Frank Myat Thu
  • 4,448
  • 9
  • 67
  • 113
  • Can you do that by specifying attributes instead of the (ugly) fluent api ? – Mariusz Jamro Jan 03 '16 at 18:55
  • Made a minor edit as somehow I managed to downvote this answer and didn't notice! Also updated it to use the preferred method for links like this `[text](link)` – DavidG Jul 10 '16 at 23:33
  • I created an empty MVC project, ran it 1 time, and the asp-named tables were created. Then I added this minor change, deleted all my tables and migration folder (for what its worth) and ran my code again, but the tables refused to be renamed. I then created an entirely new project, made this change before running, and now its working. Am I missing something very obvious?? – mathkid91 Oct 04 '16 at 19:13
  • This works in core, too, although the user DTO name is usually `IdentityUser`. You might also need to specify the type of the Key data type used, which is defaulted to string, e.g. `modelBuilder.Entity>.ToTable(...` etc. – StuartLC Jan 03 '23 at 11:53
16

You can try overriding this method in your DbContext class to map it to a table of your choosing:

    protected override void OnModelCreating(DbModelBuilder modelBuilder) {
        modelBuilder.Entity<IdentityUser>()
            .ToTable("AspNetUsers");
Hao Kung
  • 28,040
  • 6
  • 84
  • 93
  • 8
    Don't forget to call `base.OnModelCreating(modelBuilder);` or the rest of the model won't be created. – Ferruccio Oct 21 '13 at 15:33
  • I updated my question after implementing @Hao Kung's solution but the problem persists, please see my edited question above. Thanks. – user2315985 Oct 29 '13 at 12:32
5

But it does not work in .NET CORE (MVC 6) for that we need to change binding to

like

protected override void OnModelCreating(ModelBuilder builder)
{
    base.OnModelCreating(builder);

    builder.Entity<IdentityRole>().ToTable("Role");
    builder.Entity<IdentityUser>(entity => 
    {
        entity.ToTable("User");
        entity.Property(p => p.Id).HasColumnName("UserId");
    });
}

It might help someone :)

dnxit
  • 7,118
  • 2
  • 30
  • 34
5

Just for documentation purpose, for the one who comes to this post on the years anyears on the future, (like me XD), All answers given up my comment are right, but you can simplyfied with this method given by Alexandru Bucur on his blog

         //But this method is not longer supported on netcore > 2.2, so I need to fix it
         foreach (var entityType in modelBuilder.Model.GetEntityTypes())
         {
            var table = entityType.Relational().TableName;
             if (table.StartsWith("AspNet"))
             {
                 entityType.Relational().TableName = table.Substring(6);
             }
         };

        //This is the functional way on NetCore > 2.2
        foreach (var entityType in modelBuilder.Model.GetEntityTypes())
        {
            var tableName = entityType.GetTableName();
            if (tableName.StartsWith("AspNet"))
            {
                entityType.SetTableName(tableName.Substring(6));
            }
        }
sgrysoft
  • 588
  • 7
  • 14
  • 1
    I think this is a good answer when you would like to change all the table names. I would do a very minor change inside SetTableName method and add a prefix like; `entityType.SetTableName(newTableNamePrefix + tableName.Substring(6));` – salih Jun 06 '21 at 14:25
  • Will be usefull too – sGermosen Jun 07 '21 at 23:34
4

You can also create configuration classes and specify every detail of each of your Identity classes, for example:

using System.Data.Entity.ModelConfiguration;

public class ApplicationUserConfig : EntityTypeConfiguration<ApplicationUser>
{
    public UserConfig()
    {
        ToTable("Users");
        Property(u => u.LocationName).IsRequired();
    }
}

And then include these configurations in the OnModelCreating() method:

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

        modelBuilder.Configurations.Add(new ApplicationUserConfig());
        ...
    }

This will give you complete control over every aspect of the Identity classes.

Manish
  • 1,726
  • 3
  • 23
  • 29
3

Also can do it dynamically such as the below:

public class ApplicationDbContext : IdentityDbContext
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options):  base(options)
    {
    }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);

        var entityTypes = builder.Model.GetEntityTypes(); 
        foreach (var entityType in entityTypes)
            builder.Entity(entityType.ClrType)
                   .ToTable(entityType.GetTableName().Replace("AspNet", ""));
    }

}
Osama AbuSitta
  • 3,918
  • 4
  • 35
  • 51
2

We can change asp.net Identity default table names like this:

    public class ApplicationDbContext : IdentityDbContext
    {    
        public ApplicationDbContext(): base("DefaultConnection")
        {
        }

        protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Entity<IdentityUser>().ToTable("user");
            modelBuilder.Entity<ApplicationUser>().ToTable("user");

            modelBuilder.Entity<IdentityRole>().ToTable("role");
            modelBuilder.Entity<IdentityUserRole>().ToTable("userrole");
            modelBuilder.Entity<IdentityUserClaim>().ToTable("userclaim");
            modelBuilder.Entity<IdentityUserLogin>().ToTable("userlogin");
        }
    }

Furthermore we can extend each class and add any property to classes like 'IdentityUser', 'IdentityRole', ...

    public class ApplicationRole : IdentityRole<string, ApplicationUserRole>
{
    public ApplicationRole() 
    {
        this.Id = Guid.NewGuid().ToString();
    }

    public ApplicationRole(string name)
        : this()
    {
        this.Name = name;
    }

    // Add any custom Role properties/code here
}


// Must be expressed in terms of our custom types:
public class ApplicationDbContext 
    : IdentityDbContext<ApplicationUser, ApplicationRole, 
    string, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>
{
    public ApplicationDbContext()
        : base("DefaultConnection")
    {
    }

    static ApplicationDbContext()
    {
        Database.SetInitializer<ApplicationDbContext>(new ApplicationDbInitializer());
    }

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

    // Add additional items here as needed
}

To save time we can use AspNet Identity 2.0 Extensible Project Template to extend all the classes.

Saber
  • 5,150
  • 4
  • 31
  • 43
2
protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Entity<AppUser>().ToTable("Users");
            modelBuilder.Entity<IdentityUser>().ToTable("Users");
            modelBuilder.Entity<IdentityRole>().ToTable("Role");
            modelBuilder.Entity<IdentityUserRole<string>>().ToTable("UserRole");
            modelBuilder.Entity<IdentityUserClaim<string>>().ToTable("UserClaim");
            modelBuilder.Entity<IdentityUserLogin<string>>().ToTable("UserLogin");
        }
Ragab Mohamad
  • 371
  • 2
  • 4
0

For .net 6 you need to use the Duende.IdentityServer.EntityFramework.Entities

        protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Entity<IdentityUser>().ToTable("SecurityUsers");  
        modelBuilder.Entity<IdentityRole>().ToTable("SecurityRole");
        modelBuilder.Entity<IdentityUserRole<string>>().ToTable("SecurityUserRole");
        modelBuilder.Entity<IdentityUserClaim<string>>().ToTable("SecurityUserClaim");
        modelBuilder.Entity<IdentityUserLogin<string>>().ToTable("SecurityUserLogin");
        modelBuilder.Entity<IdentityRoleClaim<string>>().ToTable("SecurityRoleClaims");
        modelBuilder.Entity<IdentityUserToken<string>>().ToTable("SecurityUserTokens");

        modelBuilder.Entity<Duende.IdentityServer.EntityFramework.Entities.PersistedGrant>().ToTable("SecurityPersistedGrant");
        modelBuilder.Entity<Duende.IdentityServer.EntityFramework.Entities.Key>().ToTable("SecurityKey");
        modelBuilder.Entity<Duende.IdentityServer.EntityFramework.Entities.DeviceFlowCodes>().ToTable("SecurityDeviceCode");

    }
Eric
  • 354
  • 1
  • 3
  • 11