Поделиться через


Первая миграция кода с существующей базой данных

Примечание.

Только EF4.3 — функции, API и т. д. на этой странице были представлены в Entity Framework 4.1. При использовании более ранней версии могут быть неприменимы некоторые или все сведения.

В этой статье описывается использование code First Migrations с существующей базой данных, которая не была создана Entity Framework.

Примечание.

В этой статье предполагается, что вы знаете, как использовать code First Migrations в основных сценариях. Если вы этого не сделали, прежде чем продолжить, вам потребуется прочитать code First Migrations .

Шаг 1. Создание модели

Первым шагом будет создание модели Code First, предназначенной для существующей базы данных. В разделе "Код в первую очередь к существующей базе данных " приведены подробные рекомендации по этому вопросу.

Примечание.

Перед внесением изменений в модель, требующей изменений в схеме базы данных, важно выполнить остальные действия, описанные в этом разделе. Для выполнения следующих действий требуется, чтобы модель была синхронизирована с схемой базы данных.

Шаг 2. Включение миграции

Следующим шагом является включение миграции. Это можно сделать, выполнив команду Enable-Migrations в консоли диспетчер пакетов.

Эта команда создаст папку в решении с именем Migrations и поместит в нее один класс с именем Configuration. Класс конфигурации , где вы настраиваете миграции для приложения, вы можете узнать больше об этом в разделе "Миграция кода в первую очередь".

Шаг 3. Добавление начальной миграции

После создания и применения миграции к локальной базе данных может потребоваться применить эти изменения к другим базам данных. Например, локальная база данных может быть тестовой базой данных, и вы можете в конечном итоге применить изменения к рабочей базе данных и /или другим тестовых базам данных разработчиков. На этом шаге есть два варианта, и то, что нужно выбрать, зависит от того, является ли схема любой другой базы данных пустой или в настоящее время соответствует схеме локальной базы данных.

  • Вариант Один. Используйте существующую схему в качестве отправной точки. Этот подход следует использовать, если другие базы данных, к которым будет применяться миграция в будущем, будут иметь ту же схему, что и локальная база данных. Например, вы можете использовать это, если локальная тестовая база данных в настоящее время соответствует версии 1 рабочей базы данных, а затем примените эти миграции для обновления рабочей базы данных до версии 2.
  • Вариант Два. Используйте пустую базу данных в качестве отправной точки. Этот подход следует использовать, если другие базы данных, к которым будут применяться миграции в будущем, пусты (или еще не существуют). Например, вы можете использовать это, если вы начали разработку приложения с помощью тестовой базы данных, но без миграций, и позже вы хотите создать рабочую базу данных с нуля.

Вариант Один. Использование существующей схемы в качестве отправной точки

При первой миграции кода используется моментальный снимок модели, хранящийся в последней миграции, для обнаружения изменений в модели (подробные сведения об этом можно найти в разделе "Миграция кода в средах групп"). Так как предполагается, что базы данных уже имеют схему текущей модели, мы создадим пустую миграцию (no-op), которая имеет текущую модель в виде моментального снимка.

  1. Выполните команду Add-Migration InitialCreate –IgnoreChanges в консоли диспетчер пакетов. При этом создается пустая миграция с текущей моделью в виде моментального снимка.
  2. Выполните команду Update-Database в консоли диспетчер пакетов. Примените миграцию InitialCreate к базе данных. Так как фактическая миграция не содержит никаких изменений, она просто добавит строку в таблицу __MigrationsHistory, указывающую, что эта миграция уже применена.

Вариант Два. Использование пустой базы данных в качестве отправной точки

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

  1. Выполните команду Add-Migration InitialCreate в консоли диспетчер пакетов. При этом создается миграция для создания существующей схемы.
  2. Закомментируйте весь код в методе Up созданной миграции. Это позволит нам "применить" миграцию к локальной базе данных, не пытаясь воссоздать все таблицы и т. д., которые уже существуют.
  3. Выполните команду Update-Database в консоли диспетчер пакетов. Примените миграцию InitialCreate к базе данных. Так как фактическая миграция не содержит никаких изменений (так как мы временно закомментировали их), она просто добавит строку в таблицу __MigrationsHistory, указывающую, что эта миграция уже применена.
  4. Отмена примечания кода в методе Up. Это означает, что при применении этой миграции к будущим базам данных схема, уже существующая в локальной базе данных, будет создана миграцией.

Необходимо учитывать следующие моменты:

При использовании миграций с существующей базой данных необходимо учитывать несколько моментов.

Имена по умолчанию и вычислениям могут не соответствовать существующей схеме

Миграции явно указывают имена столбцов и таблиц при создании шаблонов миграции. Однако существуют другие объекты базы данных, для которых миграция вычисляет имя по умолчанию при применении миграций. Сюда входят индексы и ограничения внешнего ключа. При выборе существующей схемы эти вычисляемые имена могут не совпадать с фактически существующими именами в базе данных.

Ниже приведены некоторые примеры того, когда необходимо учитывать следующее:

Если вы использовали option One: используйте существующую схему в качестве отправной точки из шага 3.

  • Если будущие изменения в модели требуют изменения или удаления одного из объектов базы данных, именуемых по-другому, необходимо изменить шаблонную миграцию, чтобы указать правильное имя. API миграции имеют необязательный параметр Name, который позволяет это сделать. Например, у существующей схемы может быть таблица Post с столбцом внешнего ключа BlogId с индексом с именем IndexFk_BlogId. Однако по умолчанию миграции ожидают, что этот индекс будет называться IX_BlogId. При внесении изменений в модель, которая приводит к удалению этого индекса, необходимо изменить шаблонный вызов DropIndex, чтобы указать имя IndexFk_BlogId.

Если вы использовали вариант "Два: использовать пустую базу данных в качестве отправной точки" из шага 3:

  • Попытка запустить метод Down начальной миграции (т. е. отменить изменения в пустую базу данных) к локальной базе данных может завершиться ошибкой, так как миграция попытается удалить индексы и ограничения внешнего ключа с использованием неправильных имен. Это повлияет только на локальную базу данных, так как другие базы данных будут созданы с нуля с помощью метода Up начальной миграции. Если вы хотите уменьшить существующую локальную базу данных до пустого состояния, проще всего сделать это вручную, либо удалить базу данных или удалить все таблицы. После этого первоначального понижения все объекты базы данных будут повторно созданы с именами по умолчанию, поэтому эта проблема снова не будет представлена.
  • Если будущие изменения в модели требуют изменения или удаления одного из объектов базы данных, именованных по-другому, это не будет работать с существующей локальной базой данных, так как имена не будут соответствовать значениям по умолчанию. Однако он будет работать с базами данных, созданными "с нуля", так как они будут использовать имена по умолчанию, выбранные миграцией. Эти изменения можно внести вручную в локальную существующую базу данных или рассмотреть возможность повторной миграции базы данных с нуля, так как она будет выполняться на других компьютерах.
  • Базы данных, созданные с помощью метода Up начальной миграции, могут немного отличаться от локальной базы данных, так как будут использоваться вычисляемые имена по умолчанию для индексов и ограничений внешнего ключа. Вы также можете в конечном итоге получить дополнительные индексы, так как миграции будут создавать индексы для столбцов внешнего ключа по умолчанию. Это может быть не так в исходной локальной базе данных.

Не все объекты базы данных представлены в модели

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

Ниже приведены некоторые примеры того, когда необходимо учитывать следующее:

  • Независимо от варианта, выбранного на шаге 3, если будущие изменения в модели требуют изменения или удаления этих дополнительных объектов, миграции не будут знать, чтобы внести эти изменения. Например, если удалить столбец с дополнительным индексом, миграции не будут знать, чтобы удалить индекс. Необходимо вручную добавить это в шаблон миграции.
  • Если вы использовали вариант "Два: использовать пустую базу данных в качестве отправной точки", эти дополнительные объекты не будут созданы методом Up начальной миграции. Вы можете изменить методы Up и Down, чтобы заботиться об этих дополнительных объектах, если вы хотите. Для объектов, которые не поддерживаются в API миграций , например представления, можно использовать метод Sql для запуска необработанного SQL для создания и удаления их.