Перенос приложений из EF6 в EF Core

Entity Framework Core, или EF Core, представляет собой полную переработку Entity Framework для современных архитектур приложений. Из-за фундаментальных изменений прямой путь обновления отсутствует. Цель этой документации — предоставить полное руководство по переносу приложений EF6 в EF Core.

Важно!

Прежде чем начать перенос, следует убедиться, что EF Core соответствует требованиям приложения к доступу к данным. Все необходимое можно найти в документации по EF Core.

Важно!

Существует известная проблема (microsoft/dotnet-apiport #993) с анализатором переносимости, который ошибочно сообщает о несовместимости EF Core с .NET 5 и .NET 6. Эти предупреждения можно спокойно игнорировать, так как EF Core полностью совместим с целевыми платформами .NET 5 и .NET 6.

Причины для обновления

Все новые разработки Entity Framework происходят в EF Core. Обратный перенос новых функций в EF6 не планируется. EF Core работает в последних средах выполнения .NET и использует все преимущества среды выполнения, зависящие от платформы, (например, ASP.NET Core или WPF) и специфические для языка функции. Ниже приведены некоторые преимущества, которые вы получаете при обновлении:

  • Воспользуйтесь преимуществами текущих улучшений производительности в EF Core. Например, одному клиенту, выполнившему миграцию с EF6 на EF Core 6, удалось в 40 раз сократить использование крупных запросов благодаря функции разделения запросов. Многие клиенты сообщают об огромном росте производительности благодаря простому переходу на последнюю версию EF Core.
  • Используйте новые возможности в EF Core. Новые функции не будут добавлены в EF6. Все новые функции, например поставщик Azure Cosmos DB и DbContextFactory, будут добавляться только в EF Core. Полное сравнение EF6 с EF Core, включая несколько функций, эксклюзивных для EF Core, см. в статье "Сравнение EF Core и EF6".
  • Модернизируйте стек приложений, используя внедрение зависимостей, и бесшовно интегрируйте доступ к данным с такими технологиями, как gRPC и GraphQL.

Примечание о миграции

В этой документации используются термины перенос и обновление, чтобы избежать путаницы с термином миграция в качестве функции EF Core. Миграции в EF Core несовместимы с миграциями EF6 Code First из-за значительных улучшений в способе обработки миграций. Не существует рекомендуемого подхода к переносу журнала миграции, поэтому в EF Core придется начать с нуля. Вы можете поддерживать базу кода и данные из миграций EF6. Примените окончательную миграцию в EF6, а затем создайте начальную миграцию в EF Core. Вы сможете вести журнал в EF Core с этого момента.

Действия по обновлению

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

Определение варианта EF Core

Существует несколько способов работы EF Core с моделью предметной области и реализацией базы данных. Как правило, большинство приложений используют один из этих шаблонов, и способ переноса зависит от варианта приложения.

Код как источник истины — это подход, при котором все моделируется с помощью кода и классов, будь то атрибуты данных, конфигурация Fluent или их сочетание. Изначально база данных создается на основе модели, определенной в EF Core, и последующие обновления обычно обрабатываются с помощью миграции. Часто такой подход называется code first, но это не совсем точный термин, поскольку один из подходов заключается в том, чтобы начать с существующей базы данных, создать сущности и затем продолжать с помощью кода.

Подход база данных в качестве источника истины включает в себя реконструирование или создание шаблонов кода из базы данных. При внесении изменений в схему код либо повторно создается, либо обновляется для отражения изменений. Такой подход часто называется "database first".

Наконец, более сложный подход гибридного сопоставления заключается в том, что код и база данных управляются отдельно, а EF Core используется для сопоставления между ними. Такой подход обычно обходится без миграции.

В следующей таблице приведена сводка по некоторым общим различиям:

Подход Роль разработчика Роль DBA Миграции Формирование шаблонов Репо
Code first Проектирование сущностей и проверка/настройка созданных миграций Проверка определений и изменений схемы По фиксациям Н/П Отслеживание сущностей, DbContext и миграций
Database first Реконструирование после изменений и проверка созданных сущностей Информирование разработчиков, когда изменения базы данных нуждаются в повторном формировании шаблонов Н/П По изменениям схемы Отслеживание расширений/разделяемых классов, расширяющих созданные сущности
Гибридный Обновление конфигурации Fluent для сопоставления при каждом изменении сущностей или базы данных Информирование разработчиков об изменении базы данных, чтобы они могли обновлять сущности и конфигурацию модели Неприменимо Неприменимо Отслеживание сущностей и DbContext

Гибридный подход более сложный. Он связан с дополнительными издержками по сравнению с традиционными подходами с упором на код и базу данных.

Общие сведения о влиянии перехода с EDMX

EF6 поддерживал особый формат определения модели — EDM XML (EDMX). EDMX-файлы содержат несколько определений, включая определения концептуальной схемы (CSDL), спецификации сопоставления (MSL) и определения схемы хранилища (SSDL). EF Core отслеживает схемы домена, сопоставления и базы данных с помощью внутренних графов модели и не поддерживает формат EDMX. Многие записи в блоге и статьи по ошибке утверждают, что EF Core поддерживает только подход "Code First". EF Core поддерживает все три модели приложений, описанные в предыдущем разделе. Модель можно перестроить в EF Core путем реконструирования базы данных. Если вы используете EDMX для визуального представления модели сущности, рассмотрите возможность использования инструментов EF Core Power Tools с открытым исходным кодом, которые предоставляют аналогичные возможности для EF Core.

Дополнительные сведения о том, что означает отсутствие поддержки для EDMX-файлов, см. в руководстве о переносе EDMX.

Выполнение действий по обновлению

Вам необязательно переносить все приложение. EF6 и EF Core могут выполняться в одном приложении (см. раздел об использовании EF Core и EF6 в одном приложении). Чтобы снизить риски, можно сделать следующее:

  1. Перейдите в EF6 в .NET Core, если вы еще этого не сделали.
  2. Перенесите небольшую часть приложения в EF Core и запустите его параллельно с EF6.
  3. Наконец, перенесите оставшуюся часть базы кода в EF Core и прекратите использование EF6.

Для самого переноса выполните следующие действия:

  1. Изучите изменения в поведении между EF6 и EF Core.
  2. При необходимости выполните окончательные миграции в EF6.
  3. Создайте проект EF Core.
  4. Скопируйте код в новый проект, запустите реконструирование или используйте комбинацию этих подходов.
  5. Переименуйте ссылки и сущности и поведение обновления:
    • System.Data.Entity...Microsoft.EntityFrameworkCore
    • Измените конструктор DbContext для использования параметров и/или переопределения OnConfiguring.
    • DbModelBuilder...ModelBuilder
    • Переименуйте DbEntityEntry<T> в EntityEntry<T>.
    • Перейдите с Database.Log на API Microsoft.Extensions.Logging (расширенный) или DbContextOptionsBuilder.LogTo (простой).
    • Примените изменения для WithRequired и WithOptional (см. здесь).
    • Обновите код проверки. В EF Core не встроена проверка данных, но вы можете выполнить ее самостоятельно.
    • Выполните все необходимые действия для переноса из EDMX.
  6. Выполните определенные действия на основе подхода EF Core:

Существует множество рекомендаций, касающихся всех подходов, поэтому необходимо также изучить способы решения и обхода детальных различий между EF6 и EF Core.