Mi chiedo perché, se lo è, perché Entity Framework non offre la logica per creare un nuovo oggetto con le stesse proprietà per trasferire i dati tra i livelli?
Uso gli oggetti entità generati con il framework entità.
Mi chiedo perché, se lo è, perché Entity Framework non offre la logica per creare un nuovo oggetto con le stesse proprietà per trasferire i dati tra i livelli?
Uso gli oggetti entità generati con il framework entità.
Risposte:
Spetta a voi.
Molte persone ti diranno che non è una buona pratica, ma in alcuni casi puoi cavartela.
EF non ha mai giocato bene con DDD per diversi motivi, ma due spiccano: non puoi avere costruttori parametrizzati sulle tue entità e non puoi incapsulare raccolte. DDD si basa su questo, poiché il modello di dominio dovrebbe includere sia dati che comportamento.
In un certo senso, EF ti costringe ad avere un modello di dominio anemico e in questo caso puoi usare le entità come DTO. Potresti riscontrare alcuni problemi se usi le proprietà di navigazione ma puoi serializzare quelle entità e inviarle via cavo. Potrebbe non essere pratico però. Dovrai controllare la serializzazione per ogni entità che ha proprietà che non devi inviare. Il modo più semplice è semplicemente progettare classi separate su misura per il trasferimento dei dati. Le librerie come AutoMapper sono create per questo scopo.
Ad esempio: supponiamo di avere una classe chiamata Person
con la seguente definizione:
public class Person
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DateOfBirth { get; get; }
// plus a bunch of other properties relevant about a person
}
Supponendo che si desidera visualizzare un elenco di dipendenti da qualche parte, può essere pratico di inviare solo il Id
, FirstName
e LastName
. Ma dovrai inviare tutte le altre proprietà irrilevanti. Non è un grosso problema se non ti interessa la dimensione della risposta, ma l'idea generale è quella di inviare solo i dati rilevanti. D'altra parte, è possibile progettare un'API che restituisce un elenco di persone e in tal caso potrebbe essere necessario inviare tutte le proprietà, quindi ha senso serializzare e inviare le entità. In questo caso, la creazione di una classe DTO è discutibile. Ad alcune persone piace mischiare entità e DTO, altre no.
Per rispondere alla tua domanda aggiornata, EF è un ORM. Il suo compito è mappare i record del database su oggetti e viceversa. Quello che fai con quegli oggetti prima e dopo aver attraversato EF non fa parte delle sue preoccupazioni. Né dovrebbe essere.
No non lo è.
Idealmente, i DTO corrisponderanno ai repository di persistenza (ovvero le tabelle del database).
Ma le tue business class non sono necessariamente una partita. Potresti aver bisogno di classi aggiuntive, o classi separate o unite a ciò che hai nel database. Se la tua applicazione è piccola, potresti non vedere davvero questo tipo di problemi, ma in applicazioni medio-grandi, questo accadrà spesso.
Un'altra cosa è che i DTO fanno parte del dominio di qualsiasi cosa si occupi di persistenza, mentre il tuo livello aziendale non dovrebbe sapere nulla di loro.
In realtà è una pessima idea. Martin Fowler ha un articolo sui DTO locali .
Per farla breve, DTO
Pattern è stato utilizzato per il trasferimento di dati all'esterno del processo, ad esempio via cavo e non tra i livelli all'interno dello stesso processo.
No, è una cattiva pratica.
Alcuni motivi:
@JsonIgnore
dal mondo Java), ma questo porta al prossimo problema ...get
metodo dell'entità.Quindi, è più facile e sicuro utilizzare una sorta di strumento di mappatura per aiutarti in questo lavoro, mappando i campi dell'entità su un Dto.
Per completare ciò che ha detto @Dherik, i principali problemi dell'uso di oggetti entità come oggetti di trasferimento dati sono:
In una transazione, si corre il rischio di impegnare le modifiche apportate alla propria entità perché la si utilizza come DTO (anche se è possibile staccare l'entità della sessione in una transazione, la maggior parte delle volte è necessario verificare questo stato prima qualsiasi modifica sulla tua entità-DTO e assicurati che non sei in una transazione o che la sessione è stata chiusa se non vuoi che le modifiche persistano).
Dimensione dei dati condivisi tra il client e il server: a volte non si desidera inviare al client tutto il contenuto di un'entità per ridurre al minimo le dimensioni della risposta della richiesta. La separazione del DTO dall'entità è più flessibile, in modo da specializzare i dati che si desidera inviare in determinati casi d'uso.
Visibilità e manutenzione: devi gestire le tue annotazioni jpa / ibernazione sui campi della tua entità e mantenere le annotazioni jackson per serializzare in json nello stesso posto (anche se puoi separarle dall'implementazione dell'entità inserendole nell'interfaccia ereditata dal entità). Quindi, se si modifica il contenuto DTO aggiungendo un nuovo campo, un'altra persona può probabilmente pensare che sia un campo dell'entità, quindi un campo della tabella interessato nel database (anche se è possibile utilizzare l' @Transient
annotazione su tutti i campi DTO per il caso ..!).
Secondo me, crea rumore quando leggi l'entità, ma la mia opinione è sicuramente soggettiva.