我正在使用 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 迁移)?
最佳答案
以下代码使我能够满足问题中概述的集成测试场景的需求,但肯定有更好的方法吗?
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;
}
}
关于c# - EF 5,Code First - 创建一个新数据库并以编程方式运行所有迁移,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15692584/