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


Изменения поведения между EF6 и EF Core

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

Это означает, что это является высокоуровневой проверкой для рассмотрения в рамках процесса переноса. Более подробные инструкции по регистру см. в подробных случаях.

Поведение методов DbSet.Add и DbSet.Attach и графа

В EF6 при вызове метода DbSet.Add() для сущности происходит рекурсивный поиск по всем сущностям, на которые указаны ссылки в свойствах навигации. Все найденные сущности, которые еще не отслеживаются контекстом, также помечаются как добавленные. DbSet.Attach() работает так же, за исключением того, что все сущности помечаются как неизмененные.

EF Core выполняет аналогичный рекурсивный поиск, но с несколько иными правилами.

  • Если корневая сущность настроена для созданного ключа и ключ не задан, он будет помещен в Added состояние.
  • Для сущностей, найденных во время рекурсивного поиска свойств навигации:
    • Если первичный ключ сущности создан хранилищем
      • Если первичному ключу не присвоено значение, то устанавливается состояние added. Значение первичного ключа считается не присвоенным, если для типа свойства задано значение CLR по умолчанию (например, 0 для int, null для string и т. д.).
      • Если первичному ключу присвоено значение, то устанавливается состояние unchanged.
    • Если первичный ключ не создан базой данных, то сущность помещается в то же состояние, что и корневая сущность.
  • Это изменение поведения применяется только к Attach группам методов и Update группам методов. Add всегда помещает сущности в Added состояние, даже если ключ задан.
  • Attach методы помещают сущности с ключами, заданными в Unchanged состояние. Это упрощает "вставка, если новая, в противном случае оставьте ее в одиночку". Update методы помещают сущности с ключами, заданными в Modified состояние. Это упрощает "вставка, если новая, в противном случае обновите ее".

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

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

Дополнительные сведения об этих поведениях в EF Core см. в Отслеживание изменений в EF Core.

Инициализация базы данных с использованием Code First

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

  • Если конфигурация не выполняется, EF6 выберет базу данных в SQL Express или LocalDb.
  • Если строка подключения с тем же именем, что и контекст, находится в файле приложенияApp/Web.config, это подключение будет использоваться.
  • Если база данных не существует, она будет создана.
  • Если ни одной из таблиц модели нет в базе данных, то в базу данных добавляется схема для текущей модели. Если включены миграции, то они используются для создания базы данных.
  • Если база данных существует и в EF6 схема была создана ранее, то она проверяется на совместимость с текущей моделью. Если же модель изменилась с момента создания схемы, возникает исключение.

В EF Core нет таких сложных операций.

  • Подключение к базе данных должно быть явно настроено в коде.
  • Инициализация не выполняется. Для применения миграций нужно использовать DbContext.Database.Migrate(). Либо используйте DbContext.Database.EnsureCreated() и EnsureDeleted() для создания или удаления базы данных без применения миграций.

Соглашение об именовании таблиц с использованием Code First

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

В EF Core используется имя свойства DbSet, в котором предоставлена сущность в производном контексте. Если для сущности нет свойства DbSet, используется имя класса.

Дополнительные сведения см. в статье "Управление схемами баз данных".