13

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

在 Application_Start() 中:

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

在 Fepazo 配置中:

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

我什至将它添加到 FepazoContext 的构造函数中:

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

一些额外的信息:

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

我是不是忘记了什么?我可以深入挖掘以找出问题所在吗?

更新

通过TruetoDatabase.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

4 回答 4

7

根据此处的另一个答案,初始化程序在与数据库进行一些交互之前不会运行。答案解释了如何强制初始化程序立即运行。

于 2013-10-18T11:44:47.500 回答
2

In the above code snippet you are calling the Database.Initialize() method immediately after creating a context instance. In this case, the database will be created immediately after calling the Initialize() method instead of waiting until the context is used for the first time.

The Initialize() method takes a Boolean parameter that controls whether the initialization process should re-run if it has already run for the application.

Specifying false will skip the initialization process if it has already executed. A value of true will initialize the database again even if it was already initialized.

于 2013-09-01T07:22:22.500 回答
2

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

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

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

于 2018-06-14T08:32:09.200 回答
2

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

我删除了 MigrationsContextFactory 并将 true 传递给MigrateDatabaseToLatestVersion<,>Migrator 以告诉它使用当前上下文。看到这个问题最高投票的答案如何将连接字符串注入 IDbContextFactory<T> 的实例?

于 2017-05-10T14:46:38.097 回答