Entity Framework Code First: ventajas y desventajas de Fluent Api frente a las anotaciones de datos [cerrado]

120

Al crear una base de datos utilizando el código de Entity Framework primero, se puede extraer una gran parte del modelo de base de datos del código. Se pueden usar API fluidas y / o atributos para ajustar el modelo.

¿Cuáles son las ventajas y desventajas de Fluent Api en comparación con las anotaciones de datos? En otras palabras: incluso si en determinadas situaciones se pueden utilizar ambos métodos, ¿en qué casos debería prevalecer un método sobre el otro?

Sam
fuente
3
Solo una idea: lo que suelo hacer es crear un proyecto de modelo con mis POCO y luego, en el proyecto de repositorio, crear un nuevo conjunto de POCO específicamente para EF y poner mis anotaciones allí. Luego simplemente mapeo entre los dos en clases de mapeador. De esa manera, mi modelo permanece intacto y facilita agregar o cambiar mi estrategia de datos, si es necesario (por ejemplo, agregue un XmlRepository y use las mismas clases de modelo).
adimauro
1
Ahora prefiero Anotación, con EFCore y bibliotecas adicionales. (requiere menos código y todo está en un solo lugar) github.com/isukces/EfCore.Shaman : agrega y extiende atributos github.com/borisdj/EFCore.FluentApiToAnnotation : útil cuando DB ya existe, después de hacer ingeniería inversa y cambiar a CodeFirst
borisdj

Respuestas:

141

Todo lo que puede configurar con DataAnnotations también es posible con Fluent API. Lo opuesto no es verdad. Entonces, desde el punto de vista de las opciones de configuración y la flexibilidad, Fluent API es "mejor".

Ejemplos de configuración (seguro que no es una lista completa) que son posibles en la API Fluent pero no con DataAnnotations (por lo que puedo ver):

  • Desactivar eliminaciones en cascada:

    .WillCascadeOnDelete(false)

  • Especifique el nombre de la columna de clave externa en la base de datos cuando la clave no esté expuesta en su modelo de objeto:

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

  • Ajuste granular fino de las relaciones, especialmente en todos los casos en los que solo se expone un lado de una asociación en el modelo de objetos:

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

  • Especificación del mapeo de herencia entre el modelo de objetos y las tablas de la base de datos (tabla por jerarquía, tabla por tipo, tabla por clase de concreto):

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

Editar: Microsoft considera la API Fluent como una "característica avanzada" (cita de aquí ):

La API fluida se considera una función más avanzada y le recomendamos que utilice anotaciones de datos a menos que sus requisitos requieran que utilice la API fluida.

Pero en mi opinión, alcanza las limitaciones de DataAnnotations muy rápidamente (excepto quizás para modelos de objetos extremadamente simples). Si ya no puede ajustar su modelo con DataAnnotations, su último recurso es seguir las convenciones de mapeo predeterminadas (nombrando sus propiedades de acuerdo con esas reglas). Actualmente no puede sobrescribir las convenciones (solo deshabilítelas; MS anunció que ofrecerá opciones de configuración para las convenciones en futuras versiones de EF). Pero si no quiere verse obligado por las convenciones de mapeo cuando defina su modelo de objeto, su única opción es la API Fluent.

Aprender la API fluida es casi imprescindible, en mi humilde opinión, las anotaciones de datos son una buena opción para aplicaciones simples.

Slauma
fuente
2
Soy un novato en este campo. ¿Se puede usar Fluent API para validar interfaces de usuario como lo hace DataAnnotation?
Bésame la axila
27
@CounterTerrorist: No lo creo. Por ejemplo: si coloca el [Required]atributo en una propiedad en una aplicación ASP.NET MVC, EF y MVC lo usarán con fines de validación porque ambos pueden procesar este atributo. Pero MVC no comprenderá la configuración de la API Fluent. Entonces, si elimina el atributo y lo usa HasRequireden Fluent API en su lugar, para EF será lo mismo pero no para MVC. (En mi opinión, los atributos deberían haber sido nombrados de manera diferente, el uso del espacio de nombres DataAnnotations de diferentes componentes y para diferentes propósitos es muy confuso).
Slauma
4
Además, tenga en [DefaultValue()]cuenta que tampoco es posible en Fluent Either.
webnoob
4
MinValue es un atributo que no se puede definir a través de Fluent API (Programming Entity Framework: Code First) (fuente: NAA eliminado por The Cog )
Serge Ballesta
7
Desde un punto de vista arquitectónico, supongo Fluent APIque mantendría tu lógica de implementación en tu DbContexty mantendría tu POCOs limpia
Luke T O'Brien