EF 5,code首先 - 创建一个新的数据库和编程运行所有迁移 [英] EF 5, Code First - Create a new database and run all migrations programatically

查看:140
本文介绍了EF 5,code首先 - 创建一个新的数据库和编程运行所有迁移的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用实体框架code首先迁移,和我遇到的情况,我想运行一个套件的集成测试。每次运行测试,我想重新创建数据库,并应用所有迁移

I'm using Entity Framework Code First migrations, and I have a scenario where I want to run a suite of integration tests. Each time the tests run, I want to re-create the database, and apply all migrations

的步骤应该是:


  1. 删除现有的测试数据库(如果有的话)

  2. 创建一个新的测试数据库,并运用所有迁移

  3. 种子数据

这是我添加迁移到现有的项目,我用启用的迁移命令来创建一个包含code到所有表添加到我的数据库中的InitialCreate迁移。

This is an existing project that I've added migrations to, and I used the Enable-Migrations command to create an "InitialCreate" migration that contains code to add all the tables to my database.

在code在我的自定义 IDatabaseInitializer 如下:

The code in my custom IDatabaseInitializer is as follows:

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迁移的最多方法没有得到这个code调用,这是不是我的预期。相反,当 Database.Create()方法被调用的所有表的创建。我需要的InitialCreate迁移到运行,因为我有额外的code在那里创建存储过程。

The Up method of my InitialCreate migration is not getting called by this code, which is not what I expected. Instead, all of the tables are created when the Database.Create() method is called. I need the InitialCreate migration to run because I have additional code in there to create stored procedures.

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

So my questions is, how do I programmatically create a new database and run all migrations (including the InitialCreate migration)?

推荐答案

以下code已经让我满足我的集成测试场景中的问题列出的需要,但肯定有一个更好的办法?

The following code has allowed me to meet the needs of my integration testing scenario outlined in the question, but surely there's a better way?

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;
    }
}

这篇关于EF 5,code首先 - 创建一个新的数据库和编程运行所有迁移的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆