Update: I completely rewrite my answer because I learned a lot more about this process and realized that my answer was almost not complete enough.
At first . I created my entities that inherit from IdentityXXX Identity classes (for example only):
using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.Security.Claims; using System.Threading.Tasks; using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity.EntityFramework; using NTier.Web.Core.Interfaces.Common; using NTier.Web.Core.Interfaces.DataModels; using NTier.Web.Core.Interfaces.Stores; namespace NTier.Web.DataAccess.Entities { public sealed class MemberEntity : IdentityUser<Guid, MemberLogin, MemberRole, MemberClaim>, IMemberDataModel, IAuditable { public MemberEntity() { Id = Guid.NewGuid(); } #region Overrides of IdentityUser<Guid,MemberLogin,MemberRole,MemberClaim> public override Guid Id { get { return base.Id; } set { base.Id = value != Guid.Empty ? value : base.Id; } } #region Overrides of IdentityUser<Guid,MemberLogin,MemberRole,MemberClaim> public override string PasswordHash { get { return base.PasswordHash; } set { base.PasswordHash = !string.IsNullOrWhiteSpace(value) ? value : base.PasswordHash ; } } #endregion #endregion public Guid Identity { get { return Id; } set { if (value != Guid.Empty) { Id = value; } } } public string Moniker { get; set; } [MaxLength(256)] public string FirstName { get; set; } [MaxLength(256)] public string LastName { get; set; } [MaxLength(256)] public string Middle { get; set; } public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<MemberEntity, Guid> manager) { // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie); // Add custom user claims here return userIdentity; } #region Implementation of IAuditable public DateTime DateTimeCreated { get; set; } public DateTime? DateTimeModified { get; set; } public DateTime? DateTimeDeleted { get; set; } public DateTime? DateTimeArchived { get; set; } public string CreatedBy { get; set; } public string ModifiedBy { get; set; } public string DeletedBy { get; set; } public string ArchivedBy { get; set; } public bool IsDeleted { get; set; } public bool IsArchived { get; set; } #endregion } }
Secondly, I tried the OnModelCreating method in my DbContext like this:
protected override void OnModelCreating(DbModelBuilder modelBuilder) { if (modelBuilder == null) throw new ArgumentNullException("modelBuilder"); modelBuilder.Entity<WebSiteEntity>() .HasKey(site => site.Identity) .ToTable("WebSite"); #region Security modelBuilder.Entity<MemberEntity>() .ToTable("Member") .HasMany(u => u.Roles) .WithRequired() .HasForeignKey(ur => ur.UserId); modelBuilder.Entity<MemberEntity>() .HasMany(u => u.Claims) .WithRequired() .HasForeignKey(uc => uc.UserId); modelBuilder.Entity<MemberEntity>() .HasMany(u => u.Logins) .WithRequired() .HasForeignKey(ul => ul.UserId); modelBuilder.Entity<MemberEntity>() .Property(u => u.Moniker) .HasMaxLength(50) .HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute("UserNameIndex") { IsUnique = true, IsClustered = false, Order = 2 })) .HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute("MonikerIndex") { IsUnique = true, IsClustered = false, Order = 1 })); modelBuilder.Entity<MemberEntity>() .Property(u => u.LastName) .HasMaxLength(256) .HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute("UserNameIndex") { IsUnique = true, IsClustered = false, Order = 3 })) .HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute("MonikerIndex") { IsUnique = true, IsClustered = false, Order = 2 })); ; modelBuilder.Entity<MemberEntity>() .Property(u => u.FirstName) .HasMaxLength(256) .HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute("UserNameIndex") { IsUnique = true, IsClustered = false, Order = 4 })) .HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute("MonikerIndex") { IsUnique = true, IsClustered = false, Order = 3 })); ; modelBuilder.Entity<MemberEntity>() .Property(u => u.Middle) .HasMaxLength(256); modelBuilder.Entity<MemberEntity>() .Property(u => u.UserName) .IsRequired() .HasMaxLength(256) .HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute("UserNameIndex") { IsUnique = true, IsClustered = false, Order = 1 })) .HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute("MonikerIndex") { IsUnique = true, IsClustered = false, Order = 4 })); modelBuilder.Entity<MemberEntity>() .Property(u => u.Email) .HasMaxLength(256); modelBuilder.Entity<MemberRole>() .HasKey(userRole => new { userRole.UserId, userRole.RoleId }) .ToTable("MemberRole"); modelBuilder.Entity<MemberLogin>() .HasKey(login => new { login.UserId, login.ProviderKey, login.LoginProvider }) .ToTable("MemberLogin"); modelBuilder.Entity<MemberClaim>() .ToTable("MemberClaim"); modelBuilder.Entity<RoleEntity>() .ToTable("Role"); modelBuilder.Entity<RoleEntity>() .Property(r => r.Name) .IsRequired() .HasMaxLength(256) .HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute("RoleNameIndex") { IsUnique = true })); modelBuilder.Entity<RoleEntity>() .HasMany(r => r.Users) .WithRequired() .HasForeignKey(ur => ur.RoleId); #endregion