我正在使用Entity Framework Code First迁移,我有一个场景,我想运行一套集成测试。每次测试运行时,我都想重新创建数据库,并应用所有迁移
步骤应该是:
这是我已添加迁移的现有项目,我使用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迁移)?
答案 0 :(得分:5)
以下代码使我能够满足问题中概述的集成测试场景的需求,但肯定有更好的方法吗?
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;
}
}
答案 1 :(得分:2)
只需删除&#34;创建数据库&#34;步骤并自行使用迁移。我在GitHub上放了一个示例项目,但重要的是
Configuration config = new Configuration();
DbMigrator migrator = new DbMigrator(config);
foreach (string s in migrator.GetPendingMigrations())
{
migrator.Update(s);
}