Le interfacce fluide sono più flessibili degli attributi e perché?


15

In una prima esercitazione sul codice EF 4.1 viene fornito il seguente codice:

public class Department
{
    public int DepartmentId { get; set; }
    [Required]
    public string Name { get; set; }
    public virtual ICollection<Collaborator> Collaborators { get; set; }
}

Quindi viene spiegato che l'interfaccia fluida è più flessibile:

Le annotazioni sui dati sono sicuramente facili da usare, ma è preferibile utilizzare un approccio programmatico che offre molta più flessibilità.

Viene quindi fornito l'esempio dell'uso dell'interfaccia fluida:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Department>().Property(dp => dp.Name).IsRequired();
    modelBuilder.Entity<Manager>().HasKey(ma => ma.ManagerCode);
    modelBuilder.Entity<Manager>().Property(ma => ma.Name)
        .IsConcurrencyToken(true)
        .IsVariableLength()
        .HasMaxLength(20);
}

Non riesco a capire perché l'interfaccia fluida sia presumibilmente migliore. É davvero? Dal mio punto di vista, sembra che le annotazioni dei dati siano più chiare e abbiano una sensazione semantica più chiara.

La mia domanda è: perché un'interfaccia fluida sarebbe un'opzione migliore rispetto all'utilizzo degli attributi, specialmente in questo caso?

(Nota: sono piuttosto nuovo all'intero concetto di interfacce fluide, quindi per favore non aspettatevi conoscenze precedenti su questo.)

Riferimento: http://codefirst.codeplex.com/


Questa domanda non riguarda davvero le interfacce fluenti. La differenza è tra l'utilizzo di attributi e il codice normale. Se il codice non fosse fluente, non cambierebbe molto sulla tua domanda.
svick

Le interfacce fluide di @svick sono sostanzialmente un codice normale, ma lo esprimono in modo diverso. Ci siamo spostati dalla specifica delle cose in codice semplice agli attributi, ora con interfacce fluide sembra che alcuni stiano tornando indietro e si spostino verso la specifica delle cose di nuovo nel codice. Voglio solo capire perché dovresti usare il codice invece degli attributi. Le interfacce fluide giustificano l'allontanamento dagli attributi e il ritorno alla semplice codifica di nuovo?
Tjaart,

Risposte:


13

Le annotazioni dei dati sono statiche, ad esempio questa dichiarazione del metodo non può cambiare in fase di esecuzione:

  [MinLength(5)]
  [MaxLength(20,ErrorMessage="Le nom ne peut pas avoir plus de 20 caractères")]
  public new string Name { get; set; }

L'interfaccia fluida può essere dinamica:

   if (longNamesEnabled)
   {
      modelBuilder.Entity<Manager>().Property(ma => ma.Name)
        .HasMaxLength(100);
   }
   else
   {
      modelBuilder.Entity<Manager>().Property(ma => ma.Name)
        .HasMaxLength(20);
   }

per non parlare del codice che può essere riutilizzato tra le proprietà.


2
perché pensi che la lunghezza (o qualsiasi altra proprietà) della stessa proprietà cambierebbe in fase di esecuzione?
Yusubov,

1
@ElYusubov: inizierei con gli scenari in cui non conoscevo la lunghezza del campo al momento della codifica.
Wyatt Barnett,

@WyattBarnett: può avere senso avere la lunghezza del campo come variabile solo quando i parametri del dominio vengono recuperati dinamicamente da un servizio o da una fonte esterna non digitata. Tuttavia, trattare in modo dinamico con le proprietà del dominio richiederebbe un approccio alla codifica difensiva.
Yusubov,

1
@ElYusubov potresti avere due proprietà che devono essere esattamente le stesse tranne la lunghezza, quindi le passo in una funzione che le imposta dinamicamente. Questo è il motivo per cui l'autore li ha definiti più flessibili.
Garrett Hall,

1
@ElYusubov, potresti rendere la lunghezza del campo un'impostazione nelle impostazioni del progetto, che si inserisce in app.config o web.config. Quindi, se la lunghezza di un campo del database è cambiata, è possibile modificare la lunghezza nel file .config senza ricompilare e ridistribuire l'app.
Kyralessa,

8

Non credo che tale affermazione debba essere ampiamente applicata; è molto specifico per Code First. In Code First, le annotazioni dei dati includono solo un sottoinsieme della funzionalità disponibile nell'API fluente. In altre parole, ci sono alcune configurazioni del modello che possono essere fatte solo usando l'API fluente.

Ad esempio, ecco alcune delle cose che non possono essere specificate usando le annotazioni:

  • La precisione di una proprietà DateTime
  • La precisione e la scala delle proprietà numeriche
  • Una proprietà String o Binary come lunghezza fissa
  • Una proprietà String come non unicode
  • Il comportamento all'eliminazione delle relazioni
  • Strategie di mappatura avanzate

Personalmente, tendo a utilizzare le annotazioni dei dati relative alla convalida ogni volta che è possibile poiché anche altre tecnologie come MVC possono trarne vantaggio. Per tutto il resto, preferisco l'API fluente.


Puoi fare un esempio di cosa si può fare solo usando l'API fluente? Sarebbe anche interessante sapere perché hanno scelto di farlo in questo modo. Sto cercando di comprendere API fleunt rispetto a metodi più convenzionali e framework di entità è solo un esempio. Voglio sapere perché lo preferirebbero agli attributi. A me gli attributi sembrano più corretti e leggibili.
Tjaart,

1
@Tjaart Ho aggiunto alcuni esempi. Durante la progettazione, c'erano due principi motivanti principali. Innanzitutto, consenti agli sviluppatori di scegliere. Alcune persone vedono gli attributi come una violazione del POCO, altri come la loro natura dichiarativa. In secondo luogo, sfruttare gli attributi esistenti e introdurne solo di nuovi per scenari comuni. Probabilmente sarai d'accordo sul fatto che gli esempi che ho dato sopra sono relativamente rari.
bricelam,

Ho notato che il comportamento di OnDelete sembra essere disponibile solo nell'API fluente. Riesci a pensare al motivo per cui hanno scelto di farlo in questo modo? Questo è davvero ciò che sto cercando di ottenere con questa domanda. La violazione POCO può essere una buona ragione se si condividono le classi tra progetti. Potresti finire per ottenere una dipendenza dal framework di entità che non vuoi se usi gli attributi!
Tjaart,

@Tjaart, non ricordo i motivi esatti. Mi sono unito al team verso la fine della funzione Code First e non ero qui per il suo design. Vedrò se riesco a convincere qualcun altro della squadra a soppesare.
bricelam,

1

La risposta alla tua domanda è fornita nel link.

Quindi definisci i tuoi vincoli applicabili al tuo dominio all'interno di questo metodo a livello di codice.

Fondamentalmente, è più o meno preferibile utilizzare Attributi rispetto all'approccio programmatico, in cui l'approccio programmatico ha un maggiore controllo sull'entità. Tuttavia, c'è un modo personalizzato di aggiungere attributi per decorare il tuo modello che potresti anche guardare.

Quando si utilizza questo approccio è anche possibile descrivere le relazioni tra tabelle e colonne. In conclusione, se si desidera avere un controllo più accurato sul proprio dominio, è possibile utilizzare questo nuovo approccio fornito con EF4.1.

Tuttavia, per gli scenari comuni di convalida l' applicazione degli attributi dovrebbe funzionare bene perché è affidabile per coprire la maggior parte dei casi; e inoltre potrebbe farti risparmiare tempo.


Puoi illustrare come il modo programmatico ti dà più controllo? Non lo capisco davvero a questo punto.
Tjaart

Ad esempio, prendi questo ".IsConcurrencyToken (true)" - come lo faresti su una definizione di attributo?
Yusubov,

[ConcurrencyCheck] <- che in realtà sembra più semplice
Tjaart

buona cattura, come descriveresti "relazioni tra tabelle e colonne"?
Yusubov,

[ForeignKey ("PersonId")] <- in questo modo, che probabilmente non è così semplice come .HasForeignKey (t => t.ProjectId), anche se tutto ciò che serve è lasciare che ForeignKey () prenda un lambda proprio come l'interfaccia fluente. Non spiega ancora perché uno sia migliore dell'altro.
Tjaart,

0

Il mio pensiero è che raccomandino l'API fluente per le prime implementazioni del codice perché descrivi esplicitamente come vengono create le relazioni nel database. Se si utilizzano annotazioni di dati, il database creato da Entity Framework potrebbe non essere quello previsto. Il tuo esempio iniziale è molto semplice, quindi, come te, userò semplicemente il metodo di annotazione dei dati.


Puoi fare un esempio del databse che non è quello che ti aspetti e in che modo un'interfaccia fluida impedisce che ciò accada?
Tjaart,
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.