Entity Framework Code First - Vantaggi e svantaggi di Fluent Api rispetto alle annotazioni dei dati [chiuso]


120

Quando si crea un database utilizzando Entity Framework code-first, è possibile estrarre gran parte del modello di database dal codice. È possibile utilizzare API e / o attributi fluenti per ottimizzare il modello.

Quali sono i vantaggi e gli svantaggi di Fluent Api rispetto alle annotazioni dei dati? In altre parole: anche se in determinate situazioni possono essere utilizzati entrambi i metodi, in quali casi dovrebbe prevalere un metodo sull'altro?


3
Solo un'idea: quello che faccio di solito è creare un progetto Model con i miei POCO, quindi nel progetto Repository, creare un nuovo set di POCO specificamente per EF e inserire le mie annotazioni lì. Quindi mi limito a mappare tra i due nelle classi mappatore. In questo modo, il mio modello rimane inalterato e semplifica l'aggiunta / modifica della mia strategia dati, se necessario (ad esempio, aggiungi un XmlRepository e utilizza le stesse classi del modello).
adimauro

1
Ora preferisco Annotation, con EFCore e librerie aggiuntive. (richiede meno codice e tutto è in un unico posto) github.com/isukces/EfCore.Shaman - aggiunge ed estende gli attributi github.com/borisdj/EFCore.FluentApiToAnnotation - utile quando il DB esiste già, dopo aver eseguito il reverse engineering e il passaggio a CodeFirst
borisdj

Risposte:


141

Tutto ciò che puoi configurare con DataAnnotations è possibile anche con l'API Fluent. Non è vero il contrario. Quindi, dal punto di vista delle opzioni di configurazione e della flessibilità, l'API Fluent è "migliore".

Esempi di configurazione (di sicuro non un elenco completo) che sono possibili nell'API Fluent ma non con DataAnnotations (per quanto posso vedere):

  • Disattiva eliminazioni a cascata:

    .WillCascadeOnDelete(false)

  • Specificare il nome della colonna della chiave esterna nel database quando la chiave non è esposta nel modello a oggetti:

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

  • Ottimizzazione granulare delle relazioni, soprattutto in tutti i casi in cui solo un lato di un'associazione è esposto nel modello a oggetti:

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

  • Specifica della mappatura dell'ereditarietà tra il modello a oggetti e le tabelle del database (Table-Per-Hierarchy, Table-Per-Type, Table-Per-Concrete-Class):

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

Modifica: Microsoft considera l'API Fluent come una "funzionalità avanzata" (citazione da qui ):

L'API fluente è considerata una funzionalità più avanzata e ti consigliamo di utilizzare le annotazioni dei dati a meno che i tuoi requisiti non richiedano l'utilizzo dell'API fluente.

Ma secondo me si raggiungono i limiti di DataAnnotation molto rapidamente (tranne forse per modelli di oggetti estremamente semplici). Se non è più possibile mettere a punto il modello con DataAnnotations, l'ultima risorsa è seguire le convenzioni di mappatura predefinite (denominando le proprietà in base a tali regole). Attualmente non è possibile sovrascrivere le convenzioni (solo disabilitarle; MS ha annunciato di fornire opzioni di configurazione per le convenzioni nelle future versioni di EF). Ma se non vuoi essere costretto dalle convenzioni di mappatura quando definisci il tuo modello a oggetti, la tua unica opzione è l'API Fluent.

Imparare l'API fluente è quasi un must imho, le DataAnnotations sono utili per applicazioni semplici.


2
Sono un principiante in questo campo. È possibile utilizzare Fluent API per convalidare le interfacce utente come può fare DataAnnotation?
baciami l'ascella il

27
@CounterTerrorist: non credo. Ad esempio: se si inserisce l' [Required]attributo su una proprietà in un'applicazione ASP.NET MVC, verrà utilizzato sia da EF che da MVC a scopo di convalida perché entrambi possono elaborare questo attributo. Ma MVC non capirà la configurazione dell'API fluente. Quindi, se rimuovi l'attributo e lo usi HasRequiredinvece nell'API Fluent, per EF sarà lo stesso ma non per MVC. (A mio parere gli attributi avrebbero dovuto essere denominati in modo diverso, l'uso dello spazio dei nomi DataAnnotations da componenti diversi e per scopi diversi è molto confuso.)
Slauma

4
Nota inoltre [DefaultValue()]non è possibile in Fluent Either.
webnoob

4
MinValue è un attributo che non può essere definito tramite Fluent API (Programming Entity Framework: Code First) (fonte: NAA cancellato da The Cog )
Serge Ballesta

7
Da un punto di vista architettonico, immagino Fluent APIche manterrebbe la tua logica di implementazione nella tua DbContexte manterrebbe POCOpulita la tua
Luke T O'Brien
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.