问题 MigrateDatabaseToLatestVersion未执行


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

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

一些额外的信息:

  • 通过自动创建迁移 添加迁移 看起来不错
  • 当我查询 __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();
    // <...>
}

8769
2017-08-31 16:02


起源



答案:


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


6
2017-10-18 11:44



当然,这就是我在第一句话中添加“(或至少首次访问数据库上下文)”的原因,以及为什么我说我试过了 Database.Initialize(true); 没有效果。不幸的是,这个问题的解决方案并不那么简单;) - Vincent Sels
哇,我花15分钟研究这个问题,因为我正在启动我的应用程序但没有登录(/与应用程序交互),实际上它必须与DB交互以执行迁移:') - edencorbin


答案:


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


6
2017-10-18 11:44



当然,这就是我在第一句话中添加“(或至少首次访问数据库上下文)”的原因,以及为什么我说我试过了 Database.Initialize(true); 没有效果。不幸的是,这个问题的解决方案并不那么简单;) - Vincent Sels
哇,我花15分钟研究这个问题,因为我正在启动我的应用程序但没有登录(/与应用程序交互),实际上它必须与DB交互以执行迁移:') - edencorbin


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

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


2
2018-05-10 14:46



我以为从那以后 IDatabaseInitializer<TContext>.InitializeDatabase(TContext) 接受了 TContext 参数总是只使用提供的上下文。所有其他内置的初始化程序甚至没有这个选项,所以很奇怪他们给它与框架的其余部分的行为不一致。 (抱歉咆哮)。 - binki


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

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

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


2
2018-06-14 08:32





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

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

指定  如果已经执行,将跳过初始化过程。价值 真正 即使它已经初始化,也会再次初始化数据库。


1
2017-09-01 07:22



感谢您的回答。这并不能解释为什么系统没有检测到它必须使用最新的迁移来更新数据库。我试过传球 true 作为参数 Database.Initialize() 强制升级,但即使这样也不会执行。 - Vincent Sels