Entity Framework Code First - преимущества и недостатки Fluent Api по сравнению с аннотациями к данным [закрыто]

120

При создании базы данных с использованием Entity Framework с приоритетом кода большая часть модели базы данных может быть извлечена из кода. Для точной настройки модели можно использовать Fluent API и / или атрибуты.

Каковы преимущества и недостатки Fluent Api по сравнению с аннотациями данных? Другими словами: даже если в определенных ситуациях могут использоваться оба метода, в каких случаях один метод должен преобладать над другим?

Сэм
источник
3
Просто идея: обычно я создаю проект модели с моими POCO, а затем в проекте Repository создаю новый набор POCO специально для EF и помещаю туда свои аннотации. Затем я просто сопоставляю их в классах картографирования. Таким образом, моя модель остается нетронутой и упрощает добавление / изменение моей стратегии данных, если это необходимо (например, добавить XmlRepository и использовать те же классы модели).
adimauro
1
Теперь я предпочитаю аннотацию с EFCore и дополнительными библиотеками. (требуется меньше кода, и все находится в одном месте) github.com/isukces/EfCore.Shaman - добавляет и расширяет атрибуты github.com/borisdj/EFCore.FluentApiToAnnotation - полезно, когда БД уже существует после выполнения обратного проектирования и переключения на CodeFirst
borisdj

Ответы:

142

Все, что вы можете настроить с помощью DataAnnotations, также возможно с помощью Fluent API. Обратное неверно. Итак, с точки зрения возможностей конфигурации и гибкости Fluent API «лучше».

Примеры конфигурации (конечно, не полный список), которые возможны в Fluent API, но не с DataAnnotations (насколько я могу судить):

  • Отключить каскадное удаление:

    .WillCascadeOnDelete(false)

  • Укажите имя столбца внешнего ключа в базе данных, если ключ не отображается в вашей объектной модели:

    .Map(conf => conf.MapKey("MyForeignKeyID"))

  • Тонкая настройка взаимосвязей, особенно во всех случаях, когда в объектной модели отображается только одна сторона ассоциации:

    .WithMany(...), WithOptional(...), WithRequiredDependent(...),WithRequiredPrincipal(...)

  • Спецификация сопоставления наследования между объектной моделью и таблицами базы данных (Table-Per-Hierarchy, Table-Per-Type, Table-Per-Concrete-Class):

    .Map<TDerived>(Action<EntityMappingConfiguration<TDerived>> ...)

Изменить: Microsoft считает Fluent API «расширенной функцией» (цитата отсюда ):

Свободный API считается более продвинутой функцией, и мы рекомендуем использовать аннотации к данным, если только ваши требования не требуют использования беглого API.

Но, на мой взгляд, вы очень быстро достигнете ограничений DataAnnotations (за исключением, возможно, чрезвычайно простых объектных моделей). Если вы больше не можете точно настроить свою модель с помощью DataAnnotations, ваше последнее средство - следовать соглашениям о сопоставлении по умолчанию (путем именования ваших свойств в соответствии с этими правилами). В настоящее время вы не можете перезаписывать соглашения (только отключите их; MS объявила, что предоставит параметры конфигурации для соглашений в будущих выпусках EF). Но если при определении объектной модели вы не хотите, чтобы вас принуждали к соглашению о сопоставлении, единственный вариант - это Fluent API.

Изучение Fluent API почти обязательно, имхо, DataAnnotations - полезный инструмент для простых приложений.

Slauma
источник
2
Я новичок в этой сфере. Можно ли использовать Fluent API для проверки пользовательских интерфейсов, как это может сделать DataAnnotation?
поцелуй мою подмышку
27
@CounterTerrorist: Я так не думаю. Например: если вы поместите [Required]атрибут в свойство в приложении ASP.NET MVC, он будет использоваться как EF, так и MVC для целей проверки, поскольку оба могут обрабатывать этот атрибут. Но MVC не понимает конфигурацию Fluent API. Итак, если вы удалите атрибут и HasRequiredвместо этого используете в Fluent API, для EF он будет таким же, но не для MVC. (На мой взгляд, атрибуты должны были называться по-другому, использование пространства имен DataAnnotations из разных компонентов и для разных целей очень сбивает с толку.)
Slauma
4
Также отметка [DefaultValue()]невозможна в Fluent Either.
webnoob
4
MinValue - это атрибут, который не может быть определен через Fluent API (Programming Entity Framework: Code First) (источник: NAA удалено The Cog )
Серж Баллеста
7
С архитектурной точки зрения, я предполагаю, Fluent APIчто ваша логика реализации будет сохранена в вашей, DbContextа вашаPOCO
Люк Т О'Брайен