11.886 messaggi dal 09 febbraio 2002
Contributi
Ciao,
puoi anche non usare AutoMapper per riconvertire i DTO in entità. Lo usano tutti perché è la maniera più conveniente di mappare un oggetto all'altro.

Se non vuoi usare AutoMapper, semplicemente crei un'istanza del DTO, lo passi a TryUpdateModel in modo che le sue proprietà vengano popolate con i valori indicati nel form, e poi copi a mano i valori sull'entità.

Esempio:
var dto = new BarcaDto();
TryUpdateModel(dto);
//recupero l'entità
var barca = context.Barche.Find(id);
//Copio a mano i valori sull'entità
barca.Descrizione = dto.Descrizione;
barca.Lunghezza = dto.Lunghezza;
...
//Risalvo
context.SaveChangesAsync();


Presentata così, sembra che entità e dto siano un'inutile duplicazione di codice dato che hanno una forma simile. Quindi se ti sembra un'inutile spreco di tempo torna pure ad usare l'entità, modificandola così come ti serve per la UI. Come ripeto: lo puoi fare.

In realtà, se fossi io, non consentirei mai di dare in pasto un'entità alla UI. In primo luogo perché un'entità scritta da me avrebbe quasi tutti i setter privati e la modifica sarebbe consentita solo attraverso metodi che esplicitano l'intento di chi la vuole aggiornare. Per esempio, per assegnargli uno skipper non lascerei mai che si possa fare questo:
entità.Skipper = dtoDelMegaForm.Skipper;

Piuttosto farei:
entità.ImpostaSkipperConLicenza(dtoDiRichiestaAggiornamentoSkipper.Skipper, dtoDiRichiestaAggiornamentoSkipper.Licenza);

...perché immagino che per cambiare skipper si debba verificare se la sua licenza è idonea e valida a condurre quella barca. Inoltre, non lascerei sovrascrivere il precedente Skipper perché di solito lo si deve notificare in qualche modo. Se alcune di queste condizioni vengono violate, il metodo deve sollevare un'eccezione appropriata che faccia capire bene all'utente cosa ha sbagliato a fare. E non posso mettere questa roba nel setter della proprietà perché mi andrebbe in esecuzione anche quando EF materializza l'oggetto e comunque non mi da modo di coinvolgere oggetti aggiuntivi, come la licenza che si vuol usare per condurre quella barca.

Inoltre, anziché fare un mega form di modifica, di solito faccio task-based UI, cioè mini form che hanno uno scopo specifico. In questo caso, il dto che si occupa dell'aggiornamento dello skipper conterrà solo le proprietà Skipper e Licenza. Quindi, per ogni entità ci sarà un certo numero DTO. Però capisco che per chi è abituato ad applicazioni data-driven con mega form questa roba può sembrare sovraingegnerizzazione.

ciao,
Moreno
Modificato da BrightSoul il 08 novembre 2018 21.06 -

Enjoy learning and just keep making
277 messaggi dal 03 ottobre 2006
In realtà io sono a caccia proprio di informazioni di sovraingegnerizzazione oltre che di sintassi perchè interpreto questi suggerimenti come il "giusto modo di procedere" onde evitare guai nel caso l'applicazione assumerà dimensioni impreviste.
In questo post per esempio ti ringrazio perchè mi mancava proprio questa coppia di istruzioni per capire come aggiornare correttamente il modello
var dto = new BarcaDto();
TryUpdateModel(dto);
perchè non avevo capito le potenzialità di TryUpdateModel nonostante il nome parli da se... :-)
Per quanto riguarda il DTO, sono perfettamente favorevole al suo uso ora che ho capito meglio il suo compito anche se, dato che l'applicazione che sto facendo non prevedo avrà grosse logiche di funzionamento, ero tentato a lavorare esclusivamente con le entità.
In particolare però, la divisione del codice a livelli i cui ognuno ha il suo compito, mi porta a pensare che istruzioni di questo genere

//recupero l'entità
var barca = context.Barche.Find(id);
//Copio a mano i valori sull'entità
barca.Descrizione = dto.Descrizione;
barca.Lunghezza = dto.Lunghezza;
...
//Risalvo
context.SaveChangesAsync();

non dovrebbero stare nel livello di presentazione dei dati bensì in un BLL come mostrato qui
http://www.asp.net/web-forms/tutorials/data-access/model-binding/adding-business-logic-layer

quindi sarei tentato ad utilizzare OnCallingDataMethods della Formview e spostare le tue istruzioni qui dentro
public void UpdateBarche(int barid, ModelMethodContext context)
{}

in fondo context dovrebbe contenere anche i dati che ho modificato nella formview...

Ma sono certo che mi manca ancora qualche conoscenza per capire che così facendo mi troverei poi in qualche caso nei guai.
comunque le istruzioni che mi hai fornito, messe a livello di presentazione dati funzionano alla grande, grazie
11.886 messaggi dal 09 febbraio 2002
Contributi

mi porta a pensare che istruzioni di questo genere [...] non dovrebbero stare nel livello di presentazione dei dati bensì in un BLL come mostrato qui

Certamente. Il sapere come i dati vadano letti e persistiti non è una responsabilità della view, per cui ha senso che questa logica sia relegata in un servizio applicativo.

Tale servizio potrebbe restituire DTO in fase di lettura, ad esempio:
public ServizioBarche {
  public async Task<IEnumerable<BarcaDto>> LeggiBarche() {
    ...
  }
}


Ed accettare come parametri dei Dto quando è il momento di apportare cambiamenti.
public ServizioBarche {
  public async Task AggiornaSkipperConLicenza(BarcaDto barca, SkipperDto skipper, LicenzaDto licenza) {
    ...
  }
}


Quindi l'uso di un servizio infrastrutturale come Entity Framework resta relegato all'interno di ServizioBarche e la view può restare completamente agnostica sul come di fatto vengano ottenuti o persistiti i dati.

ciao,
Moreno

Enjoy learning and just keep making

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.