EntityFramework 6 Миграции как для существующих, так и для новых баз данных?

c# entity-framework entity-framework-6 entityspaces migration

Вопрос

В нашем программном обеспечении у нас есть клиентская база с существующими базами данных. Базы данных в настоящее время доступны через EntitySpaces, но мы хотели бы переключиться на EntityFramework (v6), поскольку EntitySpaces больше не поддерживается. Мы также хотели бы использовать функцию миграции. Автоматическая миграция отключена, поскольку мы хотим разрешить миграцию базы данных только администратору.

Мы создали модель EF из существующей базы данных. Все это работает очень хорошо, но реальная проблема, которую мы имеем, заключается в программном различении существующих баз данных, соответствующих модели, но еще не преобразованных в EF (отсутствует таблица MigrationsHistory) и пустых / новых баз данных. Преобразование существующих баз данных хорошо работает с пустой миграцией, но для новых баз данных нам также нужна миграция, содержащая полную модель. Первоначальная миграция в цепочке миграции всегда сталкивается с существующими базами данных. Конечно, мы могли бы создать обходное решение с внешними сценариями SQL или командами ADO, создав и заполнив таблицу MigrationsHistory. Но этого мы бы хотели избежать, потому что некоторые из наших клиентов используют базы данных MsSql, некоторые используют Oracle. Поэтому мы действительно хотели бы сохранить уровень абстракции, предоставляемый EF.

Есть ли способ заставить EF обрабатывать как существующие, так и новые базы данных посредством миграции на основе кода, не отступая от обходных решений, отличных от EF?

Принятый ответ

Мое первоначальное предложение заключалось в том, чтобы заманить исключение, созданное с помощью CreateTable, но оказывается, что это выполняется в другом месте, поэтому это невозможно захватить в рамках исключения.

Простейшим методом продолжения будет использование метода Seed для создания исходной базы данных, если он отсутствует. Сделать это...

  1. Начиная с пустой базы данных, добавьте начальную миграцию Create и захватите сгенерированный SQL

    Add-Migration InitialCreate
    Update-Database -Script
    
  2. Сохраните этот скрипт. Вы можете добавить его в ресурс, статический файл или даже оставить его встроенным в свой код, если хотите, это зависит от вас.

  3. Удалите весь код из миграции InitialCreate (оставив его с пустой функцией Up () и Down ()). Это позволит выполнить пустую миграцию, в результате чего будет создана таблица MigrationHistory.

  4. В вашем классе конфигурации миграции вы можете динамически запрашивать и выполнять SQL, используя context.Database.SqlQuery и context.Database.ExecuteSqlCommand . Проверьте наличие основных таблиц, а если нет, выполните скрипт, сгенерированный выше.

Это не очень аккуратно, но его просто реализовать. Проверьте это хорошо, так как метод Seed запускается после каждого перехода миграции, а не только из начального. Вот почему вам нужно проверить наличие основной таблицы, прежде чем что-либо сделать.

Более сложным подходом было бы написать метод «CreateTableIfNotExists» для переноса, но это будет включать использование Reflection для вызова внутренних методов в классе DbMigration.



Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему
Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему