EF 5,Code First – 创建一个新数据库并以编程方式运行所有迁移

我正在使用Entity Framework Code First迁移,我有一个场景,我想运行一套集成测试。 每次运行测试时,我都想重新创建数据库,并应用所有迁移

步骤应该是:

  1. 删除现有的测试数据库(如果有)
  2. 创建新的测试数据库,并应用所有迁移
  3. 种子数据

这是我已添加迁移的现有项目,我使用Enable-Migrations命令创建“InitialCreate”迁移,其中包含将所有表添加到数据库的代码。

我的自定义IDatabaseInitializer的代码如下:

 public void InitializeDatabase(MyContext context) { //delete any existing database, and re-create context.Database.Delete(); context.Database.Create(); //apply all migrations var dbMigrator = new DbMigrator(new Configuration()); dbMigrator.Update(); //seed with data this.Seed(context); context.SaveChanges(); } 

我的InitialCreate迁移的Up方法没有被这段代码调用,这不是我的预期。 而是在调用Database.Create()方法时创建所有表。 我需要运行InitialCreate迁移,因为我在那里有额外的代码来创建存储过程。

所以我的问题是,如何以编程方式创建新数据库并运行所有迁移(包括InitialCreate迁移)?

以下代码使我能够满足问题中概述的集成测试场景的需求,但肯定有更好的方法吗?

 public void InitializeDatabase(MyContext context) { //delete any existing database, and re-create context.Database.Delete(); var newDbConnString = context.Database.Connection.ConnectionString; var connStringBuilder = new SqlConnectionStringBuilder(newDbConnString); var newDbName = connStringBuilder.InitialCatalog; connStringBuilder.InitialCatalog = "master"; //create the new DB using(var sqlConn = new SqlConnection(connStringBuilder.ToString())) { using (var createDbCmd = sqlConn.CreateCommand()) { createDbCmd.CommandText = "CREATE DATABASE " + newDbName; sqlConn.Open(); createDbCmd.ExecuteNonQuery(); } } //wait up to 30s for the new DB to be fully created //this takes about 4s on my desktop var attempts = 0; var dbOnline = false; while (attempts < 30 && !dbOnline) { if (IsDatabaseOnline(newDbConnString)) { dbOnline = true; } else { attempts++; Thread.Sleep(1000); } } if (!dbOnline) throw new ApplicationException(string.Format("Waited too long for the newly created database \"{0}\" to come online", newDbName)); //apply all migrations var dbMigrator = new DbMigrator(new Configuration()); dbMigrator.Update(); //seed with data this.Seed(context); context.SaveChanges(); } private bool IsDatabaseOnline(string connString) { try { using (var sqlConn = new SqlConnection(connString)) { sqlConn.Open(); return sqlConn.State == ConnectionState.Open; } } catch (SqlException) { return false; } } 

只需删除“创建数据库”步骤并自行使用迁移。 我在GitHub上放了一个示例项目,但重要的是

 Configuration config = new Configuration(); DbMigrator migrator = new DbMigrator(config); foreach (string s in migrator.GetPendingMigrations()) { migrator.Update(s); }