加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – EF 5,代码优先 – 创建一个新的数据库并以编程方式运行所

发布时间:2020-12-15 06:51:30 所属栏目:百科 来源:网络整理
导读:我正在使用实体框架代码第一次迁移,我有一个场景,我想运行一套集成测试.每次测试运行时,我想重新创建数据库,并应用所有迁移 步骤应该是: 删除现有的测试数据库(如果有的话) 创建一个新的测试数据库,并应用所有迁移 种子数据 这是我已经将迁移添加到的现有项
我正在使用实体框架代码第一次迁移,我有一个场景,我想运行一套集成测试.每次测试运行时,我想重新创建数据库,并应用所有迁移

步骤应该是:

>删除现有的测试数据库(如果有的话)
>创建一个新的测试数据库,并应用所有迁移
>种子数据

这是我已经将迁移添加到的现有项目,我使用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;
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读