MigrateDatabaseToLatestVersion未执行

时间:2013-08-31 16:02:24

标签: asp.net-mvc entity-framework ef-code-first database-migration

我无法弄清楚为什么我的最新迁移没有在应用程序启动时自动执行(或者至少在首次访问数据库上下文时)。我曾经在开发中手动运行 update-database ,但我想测试它是否会在托管测试环境中自动升级。

在Application_Start()中:

Database.SetInitializer<FepazoContext>(
    new MigrateDatabaseToLatestVersion<FepazoContext, FepazoConfiguration>())

在FepazoConfiguration中:

internal sealed class FepazoConfiguration : 
    DbMigrationsConfiguration<Fepazo.Models.FepazoContext>
{
    public FepazoConfiguration()
    {
        AutomaticMigrationsEnabled = true;
    }
}

我甚至将其添加到FepazoContext的构造函数中:

public FepazoContext() : base("DefaultConnection")
{
    Database.Initialize(false);
}

一些额外信息:

  • 通过 add-migration 自动创建迁移,看起来不错。
  • 当我查询__MigrationHistory表时,我可以看到迁移尚未被“记录”为执行。
  • 我验证了初始化程序或AutomaticMigrationsEnabled设置未在Web.config文件中被覆盖。
  • FepazoContext构造函数中的断点和FepazoConfiguration 被点击。

我忘记了什么吗?我可以深入挖掘,找出它出错的地方吗?

更新

True传递给Database.Initialize以尝试强制迁移也无效。 Database.CompatibleWithModel(true)返回false - 因此系统检测到存在差异,但是它不会执行挂起的迁移!

public FepazoContext() : base("DefaultConnection")
{
    if (!Database.CompatibleWithModel(true))
    {
        // This is executed (each time the code enters)
        Database.Initialize(true);
    }
}

解决方法

作为一种解决方法,我在设置初始化程序后立即显式调用DbMigrator.Update()。虽然我仍然想知道为什么它不会自动起作用,但这就是诀窍......

protected void Application_Start()
{
    // <...>
    Database.SetInitializer<FepazoContext>(
        new MigrateDatabaseToLatestVersion<FepazoContext, FepazoConfiguration>());
    var dbMigrator = new DbMigrator(new FepazoConfiguration());
    dbMigrator.Update();
    // <...>
}

4 个答案:

答案 0 :(得分:7)

根据another answer on here,在与数据库进行某些交互之前,初始化程序不会运行。答案解释了如何强制初始化程序立即运行。

答案 1 :(得分:2)

在上面的代码片段中,您在创建上下文实例后立即调用 Database.Initialize()方法。在这种情况下,将在调用Initialize()方法之后立即创建数据库,而不是等到第一次使用上下文。

Initialize()方法接受一个布尔参数,该参数控制初始化过程是否应该重新运行(如果已经为应用程序运行)。

指定 false 将跳过初始化过程(如果已执行)。值 true 将再次初始化数据库,即使它已经初始化。

答案 2 :(得分:2)

我有这个问题。我的问题是我有一个用于提供连接字符串的MigrationsContextFactory。发生数据库初始化时,正在调用迁移上下文工厂。此MigrationsContextFactory正在获取到另一个数据库的连接字符串,并确保它是最新的。

我删除了MigrationsContextFactory并将true传递给MigrateDatabaseToLatestVersion<,> Migrator,告诉它使用当前上下文。看到这个问题最高投票回答How do I inject a connection string into an instance of IDbContextFactory<T>?

答案 3 :(得分:2)

确保MigrateDatabaseToLatestVersion将使用应用程序正在使用的正确上下文。这是通过使用参数useSuppliedContext。

完成的
Database.SetInitializer<FepazoContext>(
    new MigrateDatabaseToLatestVersion<FepazoContext, FepazoConfiguration>(useSuppliedContext: true));

在此更改之后,我的MVC应用程序确实更新了我的数据库。