Основы сущности 6.1.3 инициализировать существующий, но пустой базе С код-первая модель


У меня возникли некоторые проблемы при подготовке заявки на выпуск в производственных системах.

Ситуация:

    [8]}Entity Framework 6.1.3 код-первая модель с несколькими миграциями
  • служба windows с выделенным пользователем serviceuser (не локальная система)
  • конфигурация (обрабатываемая WPF-приложением) позволяет вставить строку подключения, указывающую на нужную базу данных MS-SQL
  • БД должна быть подготовлена администратором установки, чтобы пользователь сервиса имеет права dbowner, dbwriter и dbreader. (должно быть достаточно для будущих миграций)
  • пользователь сервиса не должен иметь прав на SQL-серверы masterdb. Вот почему желаемая БД для службы windows должна быть создана администратором перед запуском службы

Что я пытаюсь сделать:

  • написание IDatabaseInitializer, который инициализирует существующую, но пустую базу данных при обнаружении и обновляет базу данных в случае устаревания модель

Что я пробовал:

  • Использование инициализатора MigrateDatabaseToLatestVersion => не удается, так как в подготовленной, но пустой базе данных нет таблицы _ _ MigrationHistory

  • При использовании инициализатора CreateDatabaseIfNotExists => это не удается, так как база данных уже существует, что заставляет этот инициализатор делать ... ничего

  • Написание моего собственного IDbInitializer со следующим InitializeDatabase-Метод:

    public void InitializeDatabase(RapasiDbContext context)
    {
        if (!context.Database.Exists()) //Shouldn't happen
        {                
          ... // Throw Execption: No prepared DB found
        }           
        try //Initialize the existing database, but only if not already done (force:false)
        {
            context.Database.InitializeDatabase(false);
        }
        catch (Exception ex)
        {
            Log.Fatal("Error while initializing the database", ex);
        }           
        try //Update the databse, if model is outdated
        {
            var dbMigrationConfig = new Configuration();
            if (dbMigrationConfig.AutomaticMigrationsEnabled && !context.Database.CompatibleWithModel(true))
            {
                Log.Info("database schame outdated, starting migration!");
                try
                {
                    var migrator = new DbMigrator(dbMigrationConfig);
                    migrator.Update();
                }
                catch (Exception ex)
                {
                    Log.Fatal("Error while migrating the database", ex);
                }
            }
        }
        catch (Exception ex)
        {
            Log.Fatal("No Migration-Histroy found!", ex);
        }
    }
    

Задача(ы)

  • в том виде, в котором я пытаюсь это сделать сейчас, инициализатор не вызывается вообще
  • переключение на InitializeDatabase (force: true) приводит к рекурсивному вызову моего собственного метода InitializeDatabase: (

Вопрос:

Как можно инициализировать исходящую базу данных с помощью скрипта InitialCommit-Up() из моих миграций?

Или я упускаю что-то действительно очевидное вопрос, почему такого рода инициализация БД не должна происходить? Есть ли какие-то лучшие практики для моей ситуации, которые я просто не знаю?

1 2

1 ответ:

MigrateDatabaseToLatestVersion инициализатор должен работать, даже если нет таблицы __MigrationHistory. Предполагается, что он будет создан при первом запуске миграции.

Как вы говорите в своем комментарии в исходном вопросе, вам нужно предоставить правильные значения для параметров конструктора MigrateDatabaseToLatestVersion при вызове метода SetInitializer:

Database.SetInitializer(new MigrateDatabaseToLatestVersion<RapasiDbContext, Configuration>(true, new Configuration()));

Как говорится на странице ссылки , булев параметр в конструкторе указывает, следует ли использовать информацию о соединении из контекста, который инициализация триггера для выполнения миграции. Если этот параметр отсутствует, информация о соединении будет получена из контекста, построенного с помощью конструктора по умолчанию или зарегистрированной фабрики (это может быть не то, что вам нужно).

Кроме того, я думаю, что вы, возможно, неправильно интерпретируете конфигурацию AutomaticMigrations. Это не означает, что ваши миграции будут применены автоматически, это означает, что они будут сгенерированы автоматически, если вы не запустили Add-Migration вручную после ваша модель изменилась. Я думаю, вы хотите, чтобы ваши отложенные миграции выполнялись, когда ваша база данных не обновлена, даже если автоматические миграции отключены.