È buona pratica utilizzare oggetti entità come oggetti di trasferimento dati?

19

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à che creo con il framework entità.

    
posta user2484998 02.06.2017 - 20:41
fonte

6 risposte

18

Dipende da te.

La maggior parte delle persone ti dirà che non è una buona pratica, ma in alcuni casi puoi farla franca.

EF non ha mai giocato bene con DDD per diversi motivi, ma due si distinguono: non è possibile avere costruttori con parametri sulle entità e non è possibile incapsulare le raccolte. DDD si basa su questo, dal momento che il modello di dominio dovrebbe includere sia dati che comportamenti.

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 incorrere in 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 è necessario inviare. Il modo più semplice è semplicemente progettare classi separate su misura per il trasferimento dei dati. 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 di voler visualizzare un elenco di dipendenti da qualche parte, può essere pratico inviare solo 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 restituisca un elenco di persone e in tal caso l'invio di tutte le proprietà potrebbe essere necessario, quindi ha senso serializzare e inviare le entità. In questo caso, la creazione di una classe DTO è discutibile. Ad alcune persone piace mescolare entità e DTO, altre no.

Per rispondere alla tua domanda aggiornata, EF è un ORM. Il suo compito è mappare i record del database agli oggetti e viceversa. Quello che fai con quegli oggetti prima e dopo aver attraversato EF non fa parte delle sue preoccupazioni. Né dovrebbe essere.

    
risposta data 02.06.2017 - 21:49
fonte
6

No, non lo è.

Idealmente, i DTO abbinano i tuoi repository di persistenza (ovvero le tue tabelle di database).

Ma le tue lezioni di business non sono necessariamente una corrispondenza. Potresti aver bisogno di classi aggiuntive, o separati, o classi unite a ciò che hai nel database. Se la tua applicazione è piccola, potresti non vedere questo tipo di problemi, ma in applicazioni di dimensioni medio-grandi, questo accadrà spesso.

Un'altra cosa è che le DTO fanno parte del dominio di qualunque cosa si occupi di persistenza, mentre il tuo Business Layer non dovrebbe sapere nulla su di loro.

    
risposta data 02.06.2017 - 21:34
fonte
2

In realtà è una pessima idea. Martin Fowler ha un articolo sui DTO locali .

Per farla breve, DTO Pattern è stato utilizzato per trasferire dati al di fuori del processo, ad esempio sul filo e non tra i livelli all'interno dello stesso processo.

    
risposta data 02.06.2017 - 21:19
fonte
2

No, è una cattiva pratica.

Alcuni motivi:

  1. I nuovi campi entità saranno nella Dto, per impostazione predefinita . Certo, puoi ignorare usando alcune annotazioni per non trasferire il campo (come @JsonIgnore dal mondo Java), ma questo porta al prossimo problema ...
  2. Numerose annotazioni / condizioni sull'entità . È necessario controllare cosa si desidera inviare su Dto, quando il nome di un attributo è stato modificato (questo interromperà il contratto), aggiungere alcuni attributi che non provengono dall'entità, l'ordine degli attributi, ecc. Presto vedrete il vostro semplice entità con molte annotazioni, campi extra e ogni volta sarà più difficile capire cosa sta succedendo.
  3. Meno flessibilità . Con una Dto sei libero di suddividere le informazioni in più classi, cambiare i nomi degli attributi, aggiungere nuovi attributi, ecc. Non puoi farlo facilmente con un'entità come Dto.
  4. Non ottimizzato . La tua entità sarà sempre più grande di una semplice Dto. Quindi avrai sempre più informazioni da ignorare / serializzare e probabilmente verranno trasmesse informazioni non necessarie.

Quindi, è più facile e sicuro utilizzare un qualche tipo di strumento mapper per aiutarti in questo lavoro, mappando i campi entità su una Dto.

    
risposta data 19.02.2018 - 20:22
fonte
0

Dipende dal tuo progetto, ma la maggior parte delle volte sarà meglio avere un DTO separato.

Vedi questa domanda su Stackoverflow: DTO ed entità in un oggetto? Ci sono molte buone informazioni là.

    
risposta data 02.06.2017 - 21:17
fonte
0

Per completare ciò che Dherik ha detto, i problemi principali dell'utilizzo di oggetti entità come oggetti di trasferimento dati sono:

1- In una transazione, si corre il rischio di commettere modifiche apportate all'entità perché la si utilizza come dto (anche se è possibile scollegare l'entità della sessione in una transazione, la maggior parte delle volte è necessario per verificare questo stato prima di qualsiasi modifica sul tuo entity-dto e assicurarti che non sei in una transazione o che la sessione è stata chiusa se non vuoi che le modifiche siano mantenute).

2- La dimensione dei dati condivisi tra il client e il server: a volte non si desidera inviare tutto il contenuto di un'entità al client per ridurre al minimo le dimensioni della risposta della richiesta. Il fatto di separare il dto dall'entità è flessibile per specializzare i dati che si desidera inviare in determinati casi o meno.

3- Lisciabilità e manutenzione: devi gestire le annotazioni jpa / hibernate sui campi della tua entità e mantenere le annotazioni di jackson per serializzare in json nello stesso punto (anche se puoi separarle dall'implementazione dell'entità inserendole l'interfaccia ereditata dall'entità). Quindi, se cambi il tuo contenuto di dto aggiungendo un nuovo campo, un'altra persona può probabilmente pensare che sia un campo dell'entità, quindi un campo della tabella interessato nel tuo database (anche se puoi usare l'annotazione @Transient su tutti i tuoi campi dto per il caso ..!). Secondo me, crea rumore quando leggi l'entità, ma la mia opinione è sicuramente soggettiva.

(scusate il blocco!)

    
risposta data 21.09.2018 - 10:45
fonte