I am attempting to incorporate ASP.NET Identity into a new application that currently uses a SQL script to create the database schema. As we will need to create Foreign Key
The final (working) OnModelCreating method builds on the answer provided by Hao Kung (whose answer I have accepted and to whom I have awarded the bounty) to create the Foreign Key references from the IdentityUser/ApplicationUser side rather than attempting to do the same from the other direction.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
var user = modelBuilder.Entity().HasKey(u => u.Id).ToTable("User", "Users"); //Specify our our own table names instead of the defaults
user.Property(iu => iu.Id).HasColumnName("Id");
user.Property(iu => iu.UserName).HasColumnName("UserName");
user.Property(iu => iu.Email).HasColumnName("EmailAddress").HasMaxLength(254).IsRequired();
user.Property(iu => iu.IsConfirmed).HasColumnName("EmailConfirmed");
user.Property(iu => iu.PasswordHash).HasColumnName("PasswordHash");
user.Property(iu => iu.SecurityStamp).HasColumnName("SecurityStamp");
user.HasMany(u => u.Roles).WithRequired().HasForeignKey(ur => ur.UserId);
user.HasMany(u => u.Claims).WithRequired().HasForeignKey(uc => uc.UserId);
user.HasMany(u => u.Logins).WithRequired().HasForeignKey(ul => ul.UserId);
user.Property(u => u.UserName).IsRequired();
var applicationUser = modelBuilder.Entity().HasKey(au => au.Id).ToTable("User", "Users"); //Specify our our own table names instead of the defaults
applicationUser.Property(au => au.Id).HasColumnName("Id");
applicationUser.Property(au => au.NumericId).HasColumnName("NumericId");
applicationUser.Property(au => au.UserName).HasMaxLength(50).HasColumnName("UserName");
applicationUser.Property(au => au.PasswordHash).HasColumnName("PasswordHash");
applicationUser.Property(au => au.SecurityStamp).HasColumnName("SecurityStamp");
applicationUser.Property(au => au.DisplayName).HasColumnName("DisplayName");
applicationUser.Property(au => au.Description).HasColumnName("Description");
applicationUser.Property(au => au.Email).HasColumnName("EmailAddress").HasMaxLength(254).IsRequired();
applicationUser.Property(au => au.IsConfirmed).HasColumnName("EmailConfirmed");
applicationUser.Property(au => au.Sequence).HasColumnName("Sequence");
applicationUser.Property(au => au.ExternalRef).HasColumnName("ExternalRef");
applicationUser.Property(au => au.LoggedOn).HasColumnName("LoggedOn");
applicationUser.Property(au => au.LoggedOff).HasColumnName("LoggedOff");
applicationUser.Property(au => au.LastActivity).HasColumnName("LastActivity");
applicationUser.Property(au => au.FailedLoginAttempts).IsOptional().HasColumnName("FailedLoginAttempts");
applicationUser.Property(au => au.LockedOutUntil).IsOptional().HasColumnName("LockedOutUntil");
applicationUser.Property(au => au.LockOutCycles).IsOptional().HasColumnName("LockOutCycles");
applicationUser.Property(au => au.Approved).HasColumnName("Approved");
var role = modelBuilder.Entity().HasKey(ir => ir.Id).ToTable("ApplicationRole", "Users");
role.Property(ir => ir.Id).HasColumnName("Id");
role.Property(ir => ir.Name).HasColumnName("Name");
var claim = modelBuilder.Entity().HasKey(iuc => iuc.Id).ToTable("UserClaim", "Users");
claim.Property(iuc => iuc.Id).HasColumnName("Id");
claim.Property(iuc => iuc.ClaimType).HasColumnName("ClaimType");
claim.Property(iuc => iuc.ClaimValue).HasColumnName("ClaimValue");
claim.Property(iuc => iuc.UserId).HasColumnName("UserId");
var login = modelBuilder.Entity().HasKey(iul => new { iul.UserId, iul.LoginProvider, iul.ProviderKey }).ToTable("UserLogin", "Users"); //Used for third party OAuth providers
login.Property(iul => iul.UserId).HasColumnName("UserId");
login.Property(iul => iul.LoginProvider).HasColumnName("LoginProvider");
login.Property(iul => iul.ProviderKey).HasColumnName("ProviderKey");
var userRole = modelBuilder.Entity().HasKey(iur => new { iur.UserId, iur.RoleId }).ToTable("UserRole", "Users");
userRole.Property(ur => ur.UserId).HasColumnName("UserId");
userRole.Property(ur => ur.RoleId).HasColumnName("RoleId");
}
I also liked the (brilliant yet so simple I can't think why I didn't do it before) idea of referencing the Model Builder Entity as a variable to use on each following fluent-api statement.
I referenced properties and foreign keys on both entities, although (in practice) it does not appear that this is required. On ASP.NET Identity 1.0 there was no problem omitting the property mappings, but since I have changed the names of Email and IsConfirmed database columns at least those needed to be mapped against the IdentityUser entity in ASP.NET Identity 1.1
Likewise the ApplicationUser class probably does not need to foreign key defined (as relationships are defined between the base class and the other entities) but I saw no harm in ensuring there was no assumption of additional foreign key columns on the other entity tables by adding a explicit definition - and it doesn't seem to have done any harm.