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();
    // <...>
}

Ответ 1

В соответствии с другим ответом здесь инициализатор не запускается до тех пор, пока не будет некоторое взаимодействие с базой данных. Ответ объясняет, как принудительно запустить инициализатор.

Ответ 2

В приведенном выше фрагменте кода вы вызываете метод Database.Initialize() сразу после создания экземпляра контекста. В этом случае база данных будет создана сразу после вызова метода Initialize() вместо ожидания, пока контекст будет использоваться в первый раз.

Метод Initialize() принимает Boolean-параметр, который определяет, должен ли процесс инициализации повторно запускаться, если он уже запущен для приложения.

Задание false пропустит процесс инициализации, если он уже выполнен. Значение true снова инициализирует базу данных, даже если она уже была инициализирована.

Ответ 3

У меня была эта проблема. Моя проблема оказалась в том, что у меня был MigrationsContextFactory, который использовался для предоставления строки подключения. Когда происходила инициализация базы данных, вызывался контекст миграции factory. Этот MigrationsContextFactory получал строку подключения к другой базе данных и обеспечивал ее актуальность.

Я удалил MigrationsContextFactory и передал true в MigrateDatabaseToLatestVersion<,> Migrator, чтобы сказать ему использовать текущий контекст. См. Этот вопрос, который был проголосован ответом Как добавить строку подключения в экземпляр IDbContextFactory <T> ?