Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p><strong>Update:</strong> I am completely rewriting my answer because I have learned so much more about this process and realized that my answer was nowhere near complete enough.</p> <p><strong>First</strong> I created my entities, inheriting from the IdentyXXX classes of Identity (Only supplying one here for sample):</p> <pre><code>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&lt;Guid, MemberLogin, MemberRole, MemberClaim&gt;, IMemberDataModel, IAuditable { public MemberEntity() { Id = Guid.NewGuid(); } #region Overrides of IdentityUser&lt;Guid,MemberLogin,MemberRole,MemberClaim&gt; public override Guid Id { get { return base.Id; } set { base.Id = value != Guid.Empty ? value : base.Id; } } #region Overrides of IdentityUser&lt;Guid,MemberLogin,MemberRole,MemberClaim&gt; 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&lt;ClaimsIdentity&gt; GenerateUserIdentityAsync(UserManager&lt;MemberEntity, Guid&gt; 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 } } </code></pre> <p>Second, I overrode the OnModelCreating method in my DbContext like so:</p> <pre><code>protected override void OnModelCreating(DbModelBuilder modelBuilder) { if (modelBuilder == null) throw new ArgumentNullException("modelBuilder"); modelBuilder.Entity&lt;WebSiteEntity&gt;() .HasKey(site =&gt; site.Identity) .ToTable("WebSite"); #region Security modelBuilder.Entity&lt;MemberEntity&gt;() .ToTable("Member") .HasMany(u =&gt; u.Roles) .WithRequired() .HasForeignKey(ur =&gt; ur.UserId); modelBuilder.Entity&lt;MemberEntity&gt;() .HasMany(u =&gt; u.Claims) .WithRequired() .HasForeignKey(uc =&gt; uc.UserId); modelBuilder.Entity&lt;MemberEntity&gt;() .HasMany(u =&gt; u.Logins) .WithRequired() .HasForeignKey(ul =&gt; ul.UserId); modelBuilder.Entity&lt;MemberEntity&gt;() .Property(u =&gt; 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&lt;MemberEntity&gt;() .Property(u =&gt; 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&lt;MemberEntity&gt;() .Property(u =&gt; 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&lt;MemberEntity&gt;() .Property(u =&gt; u.Middle) .HasMaxLength(256); modelBuilder.Entity&lt;MemberEntity&gt;() .Property(u =&gt; 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&lt;MemberEntity&gt;() .Property(u =&gt; u.Email) .HasMaxLength(256); modelBuilder.Entity&lt;MemberRole&gt;() .HasKey(userRole =&gt; new { userRole.UserId, userRole.RoleId }) .ToTable("MemberRole"); modelBuilder.Entity&lt;MemberLogin&gt;() .HasKey(login =&gt; new { login.UserId, login.ProviderKey, login.LoginProvider }) .ToTable("MemberLogin"); modelBuilder.Entity&lt;MemberClaim&gt;() .ToTable("MemberClaim"); modelBuilder.Entity&lt;RoleEntity&gt;() .ToTable("Role"); modelBuilder.Entity&lt;RoleEntity&gt;() .Property(r =&gt; r.Name) .IsRequired() .HasMaxLength(256) .HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute("RoleNameIndex") { IsUnique = true })); modelBuilder.Entity&lt;RoleEntity&gt;() .HasMany(r =&gt; r.Users) .WithRequired() .HasForeignKey(ur =&gt; ur.RoleId); #endregion </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload