Customizing table names for IdentityDbContextWithCustomUser data contexts

Share on:

I was playing around with Visual Studio 2013 and Entity Framework 6 in an MVC 5 application recently, and was impressed with the level of support that is provided out of the box for oAuth. If you create a new ASP.NET MVC 5 site with the Individual User Accounts authentication option and follow all the instructions on MSDN, it’s trivial getting at least Google authentication working against a new site.

If you follow the instructions through to the end, you’ll end up having a data context that derives from IdentityDbContextWithCustomUser, where TUser is your custom user entity that derives from [NAMESPACE]User.

If you just run this code as-is and examine the database, you’ll see the following tables:

1dbo.AspNetRoles 
2dbo.AspNetTokens 
3dbo.AspNetUserClaims 
4dbo.AspNetUserLogins 
5dbo.AspNetUserManagement 
6dbo.AspNetUserRoles 
7dbo.AspNetUsers 
8dbo.AspNetUserSecrets

Fantastic, but what if you want the tables to be named differently, or exist in a separate database schema? My first thought was have my data context implement the base class of IdentityDbContextWithCustomUser, IdentityDbContext<TUser, TUserClaim, TUserSecret, TUserLogin, TRole, TUserRole, TToken, TUserManagement> (that’s a lot of generic parameters there…) and provide custom implementations of each of the various generic parameters, conforming to any interface constraints, e.g. IUser, IUserManagement. That way I could change the entity shapes to suit me a bit better.

Unfortunately this approach failed - there seemed to be some logic buried deep that was still taking dependencies on the old concrete types, rather than the ones I had specified in the generic constraints. (As an aside, this is RC1, so your mileage may vary in the release candidate when it’s released)

It turns out that instead of reinventing the wheel (re-creating all the model classes), the easiest thing to do is decorate the existing wheel to suit your tastes. (Metaphor over, code follows:)

 1public class MyDataContext : IdentityDbContextWithCustomUser<Member>
 2{
 3    protected override void OnModelCreating(DbModelBuilder modelBuilder)
 4    {
 5        modelBuilder.Entity<User>()
 6            .ToTable("Member", "Security")
 7            .Property(p => p.Id).HasColumnName("MemberId");
 8
 9        modelBuilder.Entity<Member>()
10            .ToTable("Member", "Security")
11            .Property(p => p.Id).HasColumnName("MemberId");
12
13        modelBuilder.Entity<Role>()
14            .ToTable("Role", "Security")
15            .Property(p => p.Id).HasColumnName("RoleId");
16
17        modelBuilder.Entity<Token>()
18            .ToTable("Token", "Security")
19            .Property(p => p.Id).HasColumnName("TokenId");
20
21        modelBuilder.Entity<UserClaim>()
22            .ToTable("MemberClaim", "Security")
23            .Property(p => p.UserId).HasColumnName("MemberId");
24
25        modelBuilder.Entity<UserLogin>()
26            .ToTable("MemberLogin", "Security")
27            .Property(p => p.UserId).HasColumnName("MemberId");
28
29        modelBuilder.Entity<UserManagement>()
30            .ToTable("MemberManagement", "Security")
31            .Property(p => p.UserId).HasColumnName("MemberId");
32
33        modelBuilder.Entity<UserRole>()
34            .ToTable("MemberRole", "Security")
35            .Property(p => p.UserId).HasColumnName("MemberId");
36
37        modelBuilder.Entity<UserSecret>()
38            .ToTable("MemberSecret", "Security");
39
40        base.OnModelCreating(modelBuilder);
41    }
42}

Here the existing model code from the Microsoft.AspNet.Identity.EntityFramework namespace is just re-mapped to alternative table and column names. Using the above code results in the following tables being created:

1Security.Member
2Security.MemberClaim
3Security.MemberLogin
4Security.MemberManagement
5Security.MemberRole
6Security.MemberSecret
7Security.Role
8Security.Token

Hope that helps!