Entity Framework Code First - Avantages et inconvénients de Fluent Api par rapport aux annotations de données [fermé]

120

Lors de la création d'une base de données à l'aide du code Entity Framework, une grande partie du modèle de base de données peut être extraite du code. L'API et / ou les attributs Fluent peuvent être utilisés pour affiner le modèle.

Quels sont les avantages et les inconvénients de Fluent Api par rapport aux annotations de données? En d'autres termes: même si dans certaines situations les deux méthodes peuvent être utilisées, dans quels cas une méthode doit-elle prévaloir sur l'autre?

Sam
la source
3
Juste une idée: ce que je fais habituellement, c'est créer un projet de modèle avec mes POCO, puis dans le projet Repository, créer un nouvel ensemble de POCO spécifiquement pour EF, et y mettre mes annotations. Ensuite, je mappe simplement entre les deux dans les classes de mappeur. De cette façon, mon modèle reste intact et facilite l'ajout / la modification de ma stratégie de données, si nécessaire (par exemple, ajoutez un XmlRepository et utilisez les mêmes classes de modèle).
adimauro
1
Je préfère maintenant Annotation, avec EFCore et des bibliothèques supplémentaires. (nécessite moins de code et tout est au même endroit) github.com/isukces/EfCore.Shaman - ajoute et étend les attributs github.com/borisdj/EFCore.FluentApiToAnnotation - utile lorsque la base de données existe déjà, après avoir effectué une ingénierie inverse et basculé vers CodeFirst
borisdj

Réponses:

142

Tout ce que vous pouvez configurer avec DataAnnotations est également possible avec l'API Fluent. L'inverse n'est pas vrai. Ainsi, du point de vue des options de configuration et de la flexibilité, l'API Fluent est "meilleure".

Exemples de configuration (certainement pas une liste complète) qui sont possibles dans l'API Fluent mais pas avec DataAnnotations (pour autant que je sache):

  • Désactivez les suppressions en cascade:

    .WillCascadeOnDelete(false)

  • Spécifiez le nom de la colonne de clé étrangère dans la base de données lorsque la clé n'est pas exposée dans votre modèle objet:

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

  • Réglage fin et granulaire des relations, en particulier dans tous les cas où un seul côté d'une association est exposé dans le modèle objet:

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

  • Spécification du mappage d'héritage entre le modèle d'objet et les tables de base de données (Table-Per-Hierarchy, Table-Per-Type, Table-Per-Concrete-Class):

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

Edit: Microsoft considère l'API Fluent comme une "fonctionnalité avancée" (citation d' ici ):

L'API fluent est considérée comme une fonctionnalité plus avancée et nous vous recommandons d'utiliser les annotations de données à moins que vos exigences ne vous obligent à utiliser l'API fluent.

Mais à mon avis, vous atteignez très rapidement les limites de DataAnnotations (sauf peut-être pour les modèles d'objets extrêmement simples). Si vous ne pouvez plus affiner votre modèle avec DataAnnotations, votre dernier recours est de suivre les conventions de mappage par défaut (en nommant vos propriétés selon ces règles). Actuellement, vous ne pouvez pas écraser les conventions (désactivez-les uniquement; MS a annoncé qu'elle donnera des options de configuration pour les conventions dans les futures versions d'EF). Mais si vous ne voulez pas être forcé par les conventions de mappage lorsque vous définissez votre modèle d'objet, votre seule option est alors l'API Fluent.

Apprendre l'API Fluent est presque un must à mon avis, les DataAnnotations sont un outil pratique pour les applications simples.

Slauma
la source
2
Je suis un novice dans ce domaine. L'API Fluent peut-elle être utilisée pour valider les interfaces utilisateur comme DataAnnotation peut le faire?
embrasse mon aisselle le
27
@CounterTerrorist: Je ne pense pas. Par exemple: si vous placez l' [Required]attribut sur une propriété dans une application ASP.NET MVC, il sera utilisé à la fois par EF et par MVC à des fins de validation, car les deux peuvent traiter cet attribut. Mais MVC ne comprendra pas la configuration de l'API Fluent. Donc, si vous supprimez l'attribut et utilisez HasRequiredà la place dans Fluent API, ce sera le même pour EF mais pas pour MVC. (À mon avis, les attributs auraient dû être nommés différemment, l'utilisation de l'espace de noms DataAnnotations à partir de différents composants et à des fins différentes est très déroutante.)
Slauma
4
Notez également que ce [DefaultValue()]n'est pas possible dans Fluent.
webnoob
4
MinValue est un attribut qui ne peut pas être défini via Fluent API (Programming Entity Framework: Code First) (source: NAA supprimé par The Cog )
Serge Ballesta
7
D'un point de vue architectural, je suppose que Fluent APIgarderait votre logique de mise en œuvre dans votre DbContextet garder votre POCOs propre
Luke O'Brien T