Create ASP.NET Identity tables using SQL script

孤者浪人 提交于 2019-11-27 21:26:21

So the new 1.1-alpha1 bits will have something close to the following by default. This might be what you are looking for in regards to the Foreign Keys. Note: this is a bit different than 1.0 as the navigation properties changed a bit to enable the ability to specify the primary key type:

We are trying to address some of the EF migration/extensibility issues, so things hopefully will be easier with Identity 1.1-alpha1 and the upcoming 6.0.2/6.1 EF releases, but I'm not sure the updated EF packages are available on myget yet.

    var user = modelBuilder.Entity<TUser>()
        .ToTable("AspNetUsers");
    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();

    modelBuilder.Entity<TUserRole>()
        .HasKey(r => new { r.UserId, r.RoleId })
        .ToTable("AspNetUserRoles");

    modelBuilder.Entity<TUserLogin>()
        .HasKey(l => new { l.UserId, l.LoginProvider, l.ProviderKey})
        .ToTable("AspNetUserLogins");

    modelBuilder.Entity<TUserClaim>()
        .ToTable("AspNetUserClaims");

    var role = modelBuilder.Entity<TRole>()
        .ToTable("AspNetRoles");
    role.Property(r => r.Name).IsRequired();
    role.HasMany(r => r.Users).WithRequired().HasForeignKey(ur => ur.RoleId);

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<IdentityUser>().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<ApplicationUser>().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<IdentityRole>().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<IdentityUserClaim>().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<IdentityUserLogin>().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<IdentityUserRole>().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.

Not sure exactly what you are trying to achieve. It should be possible if you use the following as required:

  • modelBuilder.ComplexType // tell ef this a complex property, Just embed in table,
  • modelBuilder.Ignore // no table required.

Then when mapping foreign key fields , if you have a property that hold the Foreign key, tell ef

modelBuilder.Entity<T>().HasRequired(t => t.NAVPROP)
              .WithMany()
              .HasForeignKey(t => t.PropertyinTThatholdsFKID);   

field_id is generated by EF when it sees a need to cater for a defined relationship and there was no defined foreignkey field. So either you have the an extra relationship you dont expect or want. Or the the relationhip was not specified with the foreignkey field.

Jack

See How can I change the table names when using Visual Studio 2013 ASP.NET Identity? for more information (bottom of initial question). I think you just need to call base.onModelCreating(modelBuilder) before your fluent calls.

BEFORE your fluent calls, add:

base.onModelCreating(modelBuilder);

As far as the SQL Scripts:

Update-Database -Script

Also here is a codeproject with the schema scripted out already (although I realize the table names are different).

Edit
My Overridden OnModelCreating Method (notice the call to base.OnModelCreating(modelBuilder) call at the beginning):

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

            modelBuilder.Entity<IdentityUser>().ToTable("User");

            modelBuilder.Entity<IdentityUser>().Property(iu => iu.Id).HasColumnName("Id");
            modelBuilder.Entity<IdentityUser>().Property(iu => iu.UserName).HasColumnName("UserName");

            /*IdentityUser does not have an Email property
            modelBuilder.Entity<IdentityUser>().Property(iu => iu.Email).HasColumnName("EmailAddress").HasMaxLength(254).IsRequired(); Not sure where this is from?*/

            modelBuilder.Entity<IdentityUser>().Property(iu => iu.PasswordHash).HasColumnName("PasswordHash");
            modelBuilder.Entity<IdentityUser>().Property(iu => iu.SecurityStamp).HasColumnName("SecurityStamp");

            /*Same - dont know where this is from?
            modelBuilder.Entity<IdentityUser>().Property(iu => iu.IsConfirmed).HasColumnName("Confirmed");*/


            modelBuilder.Entity<ApplicationUser>().HasKey(au => au.Id).ToTable("User"); //Specify our our own table names instead of the defaults

            modelBuilder.Entity<ApplicationUser>().Property(au => au.Id).HasColumnName("Id");
            modelBuilder.Entity<ApplicationUser>().Property(au => au.NumericId).HasColumnName("NumericId");
            modelBuilder.Entity<ApplicationUser>().Property(au => au.UserName).HasMaxLength(50).HasColumnName("UserName");
            modelBuilder.Entity<ApplicationUser>().Property(au => au.SecurityStamp).HasColumnName("SecurityStamp");
            modelBuilder.Entity<ApplicationUser>().Property(au => au.DisplayName).HasColumnName("DisplayName");
            modelBuilder.Entity<ApplicationUser>().Property(au => au.Description).HasColumnName("Description");
            modelBuilder.Entity<ApplicationUser>().Property(au => au.Sequence).HasColumnName("Sequence");
            modelBuilder.Entity<ApplicationUser>().Property(au => au.ExternalRef).HasColumnName("ExternalRef");
            modelBuilder.Entity<ApplicationUser>().Property(au => au.LoggedOn).HasColumnName("LoggedOn");
            modelBuilder.Entity<ApplicationUser>().Property(au => au.LoggedOff).HasColumnName("LoggedOff");
            modelBuilder.Entity<ApplicationUser>().Property(au => au.LastActivity).HasColumnName("LastActivity");
            modelBuilder.Entity<ApplicationUser>().Property(au => au.FailedLoginAttempts).IsOptional().HasColumnName("FailedLoginAttempts");
            modelBuilder.Entity<ApplicationUser>().Property(au => au.LockedOutUntil).IsOptional().HasColumnName("LockedOutUntil");
            modelBuilder.Entity<ApplicationUser>().Property(au => au.LockOutCycles).IsOptional().HasColumnName("LockOutCycles");
            modelBuilder.Entity<ApplicationUser>().Property(au => au.Approved).HasColumnName("Approved");

            modelBuilder.Entity<IdentityRole>().HasKey(ir => ir.Id).ToTable("ApplicationRole");

            modelBuilder.Entity<IdentityRole>().Property(ir => ir.Id).HasColumnName("Id");
            modelBuilder.Entity<IdentityRole>().Property(ir => ir.Name).HasColumnName("Name");

            modelBuilder.Entity<IdentityUserClaim>().HasKey(iuc => iuc.Id).ToTable("UserClaim");

            modelBuilder.Entity<IdentityUserClaim>().Property(iuc => iuc.Id).HasColumnName("Id");
            modelBuilder.Entity<IdentityUserClaim>().Property(iuc => iuc.ClaimType).HasColumnName("ClaimType");
            modelBuilder.Entity<IdentityUserClaim>().Property(iuc => iuc.ClaimValue).HasColumnName("ClaimValue");
            //modelBuilder.Entity<IdentityUserClaim>().Property(iuc => iuc.UserId).HasColumnName("UserId");

            modelBuilder.Entity<IdentityUserLogin>().HasKey(iul => new { iul.UserId, iul.LoginProvider, iul.ProviderKey }).ToTable("UserLogin"); //Used for third party OAuth providers

            modelBuilder.Entity<IdentityUserLogin>().Property(iul => iul.UserId).HasColumnName("UserId");
            modelBuilder.Entity<IdentityUserLogin>().Property(iul => iul.LoginProvider).HasColumnName("LoginProvider");
            modelBuilder.Entity<IdentityUserLogin>().Property(iul => iul.ProviderKey).HasColumnName("ProviderKey");

            modelBuilder.Entity<IdentityUserRole>().HasKey(iur => new { iur.UserId, iur.RoleId }).ToTable("UserRole");

            modelBuilder.Entity<IdentityUserRole>().Property(ur => ur.UserId).HasColumnName("UserId");
            modelBuilder.Entity<IdentityUserRole>().Property(ur => ur.RoleId).HasColumnName("RoleId");


        }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!