播种Identity 2.0数据库

Lor*_*pts 10 asp.net-identity asp.net-identity-2

我有一个ASP.NET MVC 5项目(剃刀引擎),它有Identity 2.0和个人用户帐户.我正在使用Visual Studio Professional 2013

我没有找到任何明确的例子(为什么不开箱即用?)我如何为Identity 2.0数据库播种,我看到的所有示例都有一半支持,因为他们没有说明你必须实现的那个.

我使用了enable-migrations,它创建了一个带有Configuration.cs文件的Migrations文件夹.它有一个Seed方法覆盖,但是当我放置一个断点时,它注意到它永远不会被执行,实际上Identity数据库甚至都没有填充模式.

那么我必须做什么,以及第一次在数据库上创建Identity 2.0模式(连接字符串是正确的,并且存在空数据库).我如何装配种子?

在IdentityModels.cs上我有这个:public class ApplicationDbContext:IdentityDbContext {ublic ApplicationDbContext():base("DefaultConnection",throwIfV1Schema:false){}

    public static ApplicationDbContext Create() {
         return new ApplicationDbContext();
    }

    protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder) {
          base.OnModelCreating(modelBuilder);
          // to avoid the "has no keys" errors when running Update-Database on PM
          modelBuilder.Entity<IdentityRole>().HasKey<string>(r => r.Id).ToTable("AspNetRoles");
          modelBuilder.Entity<IdentityUser>().ToTable("AspNetUsers");
          modelBuilder.Entity<IdentityUserLogin>().HasKey(l => new { l.UserId, l.LoginProvider, l.ProviderKey }).ToTable("AspNetUserLogins");
          modelBuilder.Entity<IdentityUserRole>().HasKey(r => new { r.RoleId, r.UserId }).ToTable("AspNetUserRoles");
          modelBuilder.Entity<IdentityUserClaim>().ToTable("AspNetUserClaims");
     }
}    
Run Code Online (Sandbox Code Playgroud)

在Migrations/Configuration.cs中(由PM> Enable-Migrations添加)我有:

internal sealed class Configuration : DbMigrationsConfiguration<Models.ApplicationDbContext> {
    public Configuration() {
        AutomaticMigrationsEnabled = false;
    }

    protected override void Seed(Models.ApplicationDbContext context) {
         WriteReferenceData();
    }
}
Run Code Online (Sandbox Code Playgroud)

在Application_Start()方法的Global.asax.cs文件中,我添加了以下内容:

System.Data.Entity.Database.SetInitializer<Models.ApplicationDbContext>(new System.Data.Entity.MigrateDatabaseToLatestVersion<Models.ApplicationDbContext, Migrations.Configuration>());
Run Code Online (Sandbox Code Playgroud)

在IdentityConfig.cs中我也有这个DB Initializer,虽然它似乎是孤儿,因为我不知道在哪里插入它:

public class ApplicationDbInitializer : System.Data.Entity.DropCreateDatabaseIfModelChanges<Models.ApplicationDbContext> {
    protected override void Seed(ApplicationDbContext context) {
        WriteReferenceData();
        base.Seed(context);
    }
}
Run Code Online (Sandbox Code Playgroud)

最后,WriteReferenceData方法在其他类中或多或少地执行此操作:

System.Data.Entity.DbContextTransaction transaction = null;
try {
    System.Data.Entity.DbContext ctx = Models.ApplicationDbContext.Create();
    transaction = ctx.Database.BeginTransaction();
    CreateRoles(ctx);
    CreateUsers(ctx);
    CreateRoleAssociations(ctx);
    ctx.SaveChanges();
    transaction.Commit();
    succeeded = true;
}
catch (Exception ex) {
    if (transaction != null { transaction.Rollback(); transaction.Dispose(); }
    succeeed = false;
}
return succeeded;
Run Code Online (Sandbox Code Playgroud)

Ant*_*Chu 15

EF有两种不同的种子方法.一个用于数据库初始化程序,另一个用于迁移.由于您已启用迁移,我将在此处介绍如何使用迁移种子方法执行此操作...

首先,即使您已启用迁移,默认情况下EF仍使用CreateDatabaseIfNotExists数据库初始化程序.这意味着当您运行应用程序时,第一次ApplicationDbContext访问该应用程序时,将调用初始化程序,如果表已经不存在,它将从您的Code First映射创建数据库表.您没有看到创建的模式,因为您可能没有访问过数据库上下文.在新的Web应用程序中,这通常在您第一次注册用户或尝试登录时触发.

要为ASP.NET标识表提供种子,您需要做两件事.第一种是将种子逻辑添加到Seed方法中Configuration.cs.第二种是update-database通过在Package Manager控制台中运行它或使用MigrateDatabaseToLatestVersion数据库初始化程序来触发....

以下是您可以在Seed方法中创建角色和用户的示例...

public Configuration()
{
    AutomaticMigrationsEnabled = true;

    // ...
}

protected override void Seed(MyProject.Web.Models.ApplicationDbContext context)
{
    if (!context.Roles.Any())
    {
        var roleStore = new RoleStore<IdentityRole>(context);
        var roleManager = new RoleManager<IdentityRole>(roleStore);
        var role = new IdentityRole{
            Name = "Administrator"
        };
        roleManager.Create(role);
    }

    if (!context.Users.Any())
    {
        var userStore = new UserStore<ApplicationUser>(context);
        var userManager = new ApplicationUserManager(userStore);

        var user = new ApplicationUser {
            Email = "foo@bar.com",
            UserName = "SuperUser"
        };
        userManager.Create(user, "MySecretPassword1234");
        userManager.AddToRole(user.Id, "Administrator");
    }
}
Run Code Online (Sandbox Code Playgroud)

完成此操作后,您可以Update-Database从程序包管理器控制台运行以将数据库迁移到最新架构并运行Seed方法.

或者您可以MigrateDatabaseToLatestVersion通过修改上下文中的内容来更改EF以使用初始化程序IdentityModels.cs...

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext()
        : base("DefaultConnection", throwIfV1Schema: false)
    {
        Database.SetInitializer<ApplicationDbContext>(new MigrateDatabaseToLatestVersion<ApplicationDbContext, Configuration>());
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,当您运行应用程序时,第一次使用数据库上下文时,它将运行update-database并播种它.