37 messaggi dal 08 agosto 2008
Salve a tutti, fino ad oggi ho utilizzato Ibatis come ORM, ora, dovendo iniziare a sviluppare una nuova applicazione, mi sono guardato un pò in giro per vedere cosa offre il mercato ho trovato entity framework; il problema è che, per poter effettuare una scelta più consapevole, vorrei togliermi alcuni dubbi.

Premetto che uno dei vantaggi di EF è che mi sembra molto attivo mentre Ibatis (ora diventato MyIbatis) sembra quasi morto.

Da quanto ho capito EF tende a semplificare e velocizzare molto l'operatività: partendo dal db mi crea lui tutti gli oggetti nell'applicazione assieme alle CRUD, cosa che invece con Ibatis ho sempre dovuto fare a manina.

Vengo ora alle mie perplessità:

-) per varie ragioni i nomi delle tabelle e dei campi presenti nel DB sono diverse dai nomi che gli oggetti e le proprietà dovranno avere nell'applicazione: è facilmente gestibile?

-) ho sempre utilizzato sp per l'accesso alle tabelle, dalle CRUD alle varie operazioni, sia per scelta architetturale che per avere maggiori prestazioni, potrei anche pensare di laciar fare le CRUD a EF ma molte logiche complesse vorrei lasciarle sul DB, so che EF permette di gestire le SP ma per evitarne la proliferazione ho sempre fatto in modo da avere una sola SP per ogni tabella, a seconda di un parametro effettuo operazioni diverse e ritorno recordset diversi all'applicazione: è gestibile?
Per fare un esempio una SP può ritornare sia il numero di righe, che un elenco di record che il risultato di una exixst, più in generale una SP può restituire un numero o un singolo record della tabella su cui si basa o una join tra più tabelle oppure proprio nulla.

-) per avere un veloce sistema di tracciatura delle modifiche le tabelle hanno una chiave primaria (sysrecID) e una chiave logica gestita dall'applicazione: l'applicazione ragiona con la chiave logica e ogni inserimento/modifica/cancellazione inviata al db viene trasformata in un'operazione di modifica/aggiunta mettendo una data fine al record esistente e creandone uno nuovo: l'applicazione ragiona solo sui record attivi, quelli cessati vengono usati direttamente accedendo al db per verificare l'autore della modifica o per recuperare versioni precedenti.
Si può gestire tramite EF?

-) in ottica di ottenere performance migliori nel DAL ho sempre creato elenchi specifici con i soli campi necessari a popolare le varie origine dati, il tipo restituito resta sempre lo stesso (contiene quindi tutti i campi e i vari elenchi degli oggetti molti a molti) ma la SP ritorna solo i campi necessari di volta in volta.
Per evitare una proliferazione di metodi nel BL ho creato un singolo metodo strutturato così:

public IList<Attivita> elencoAttivita(IDictionary<enumNomiParametriAttivita, object> param, enumStatementAttivita statement)

il primo parametro è un elenco fatto dalla coppia (NomeParametro, valore), il secondo è il nome dell'elenco che si vuole ottenere.
E' possibile implementare qualcosa di simile?


Alla luce di tutto questo cosa ne pensate: EF può darmi dei benefici oppure il grado di personalizzazione che voglio ottenere richia di portarmi a scrivere ancora buona parte del codice a mano con in più dei vincoli alla flessibilità?
37 messaggi dal 08 agosto 2008
Nessuno mi sa dire qualcosa?
37 messaggi dal 08 agosto 2008
Sapete consigliarmi un sito dove andare a porre questa domanda?

Dovendo realizzare una nuova applicazione mi piacerebbe trovare un posto dove confrontarmi su varie scelte architetturali
11.886 messaggi dal 09 febbraio 2002
Contributi
buongiorno, benvenuto nel forum!

Provo a rispondere a tutte le due domande.

AdeptusAstartes ha scritto:

per varie ragioni i nomi delle tabelle e dei campi presenti nel DB sono diverse dai nomi che gli oggetti e le proprietà dovranno avere nell'applicazione: è facilmente gestibile?

Certo, dal designer puoi facilmente cambiare i nomi di tabelle e campi.
Questo è possibile perché nel data model di Entity Framework, lo schema dello storage (composto di tabelle, campi, relazioni e SP) sono debolmente accoppiati con il modello concettuale (classi, proprietà, associazioni e funzioni). Tra loro esiste un livello di mapping che rende possibili varie cose.
  • Cambio dei nomi
  • Rifattorizzazione di alcuni campi in un tipo complesso. Ad esempio: se nella tabella Ordine hai i campi Via, Città, Provincia e Comune, questi possono essere raggruppati logicamente in un tipo complesso chiamato "Indirizzo" che puoi usare come proprietà dell'entità Ordine.
  • Ereditarietà. Entity Framework ti consente di riappropriarti di uno dei pilastri della programmazione orientata agli oggetti. Le entità (classi) che hai nel modello concettuale, non devono per forza rimappare 1:1 con tabelle del database. Puoi creare più entità derivate che rimappano ad una singola tabella, in cui è presente un campo che funziona da discriminatore. Oppure puoi splittare una singola entità su più tabelle. Hai sufficiente spazio di manovra per creare un modello idoneo. Dopotutto tra i compiti di un ORM c'è quello di ridurre il conflitto di impedenza che esiste tra il modello relazionale e il modello orientato agli oggetti.


AdeptusAstartes ha scritto:

potrei anche pensare di lasciar fare le CRUD a EF

Sì, puoi lasciarglielo fare perché il DbContext di Entity Framework eseguirà i comandi UPDATE, INSERT e DELETE nel contesto di una transazione. Questo comportamento è perfetto anche quando stai salvando un'entità Ordine e le tutte le sue entità correlate LineaOrdine. Con una sola invocazione al metodo .SaveChanges del DbContext, tutte le entità verranno persistite e tu avrai la sicurezza che il database si troverà in uno stato consistente sia che l'aggiornamento abbia avuto successo sia che si sia verificato un errore.

AdeptusAstartes ha scritto:

ma molte logiche complesse vorrei lasciarle sul DB, so che EF permette di gestire le SP

Sì, verranno importate come funzioni nel DbContext. Inoltre, se vuoi, puoi mappare la SP all'operazione di Insert, Update o Delete di un'entità. EF invocherà la stored procedure anziché inviare l'opportuno comando al database.

AdeptusAstartes ha scritto:

per evitarne la proliferazione ho sempre fatto in modo da avere una sola SP per ogni tabella, a seconda di un parametro effettuo operazioni diverse e ritorno recordset diversi all'applicazione: è gestibile?

Comprendo la scelta, è una decisione molto "umana" quella di voler tenere tutto in ordine. In realtà, creando una sola SP per ogni tabella hai solo nascosto la polvere sotto al tappeto.
Se stai scrivendo un software di qualità, dovrai comunque documentare ogni operazione che ciascuna SP è in grado di fare, quindi il lavoro non sarà diminuito.
A spaventarti non dovrebbe essere il numero di stored procedure ma la loro cripticità, specie se le progetti in modo che restituiscano risultati diversi in base ai parametri in ingresso.
E' preferibile, secondo me, averne molte e molto semplici anziché averne poche ma più complesse. Anche se sono tante, potrai pur sempre organizzarle in schemi diversi. Il data model di Entity Framework infatti può lavorare con oggetti database provenienti da più schemi.

Chiediti questo: se il progetto dovesse passare in mano ad un altro sviluppatore, riuscirebbe subito a capire come usare le tue stored procedures o dovresti fornirgli assistenza?

Comunque, per rispondere alla tua domanda: quando importi una stored procedure nel designer di Entity Framework, devi anche indicare un tipo di ritorno che non può cambiare da caso a caso. Il C# è un linguaggio staticamente tipizzato.

Sei comunque libero di inviare query arbitrarie al database, e quindi anche di eseguire SP con determinati parametri. Leggi questo articolo, ti mostra come ottenere da una query SQL un elenco di entità oppure di un tipo a tua scelta (es. un elenco di stringhe).
http://msdn.microsoft.com/en-US/data/jj592907

In questo modo però vai a mettere le mani nello storage mentre tu, avendo scelto di usare un ORM, dovresti teoricamente interrogare solo il modello concettuale.

AdeptusAstartes ha scritto:

inserimento/modifica/cancellazione inviata al db viene trasformata in un'operazione di modifica/aggiunta. Si può gestire tramite EF?

Sì, come dicevo poc'anzi potresti mappare 3 stored procedures alle operazioni Insert, Update e Delete dell'entità. Queste SP potrebbero compiere la modifica/aggiunta di cui parlavi.

In alternativa, potresti lasciare che EF invii liberamente i suoi comandi CUD e poi intercettare il comando nel database con un TRIGGER INSTEAD OF. Così non dovrai perdere tempo a mappare ogni-singola-stored-procedure su ogni-singola-entità.

Mi sembra che l'uso di un trigger ti possa garantire una maggiore consistenza dei dati. Senza trigger, infatti, io potrei eliminarti dei record dalla tabella eseguendo una DELETE dal Sql Server Management Studio. Invece tu vuoi che nessun record vada perso ma che, casomai, il suo campo DataFine venga aggiornato.

AdeptusAstartes ha scritto:

Per evitare una proliferazione di metodi nel BL ho creato un singolo metodo strutturato così

Non serve, infatti puoi proiettare un'entità su un tipo a tua scelta. Può trattarsi anche di un tipo anonimo, cioè di un tipo creato dal compilatore e che non esiste nel tuo codice sorgente.
Ad esempio, volendo ottenere da un Ordine solo il Totale il numero di righe d'ordine, puoi usare il metodo .Select per proiettare solo quelle due informazioni.
var contesto = new MioDbContext();

//estraggo solo i campi Totale e il numero di righe.
//la variabile risultato sarà un elenco di un tipo anonimo che ha solo le proprietà Totale e NumeroRighe.
var risultato = contesto.Ordini.Select(ordine=>new {ordine.Totale, NumeroRighe=ordine.RigheOrdine.Count()}).ToList();

contesto.Dispose();

//metto in binding il risultato
gridView.DataSource = risultato;
gridView.DataBind();
EF preparerà una SELECT SQL comprendente solo i campi che hai menzionato nella tua query. Così ottimizzerai il trasferimento dati tra il database server e il web server.

AdeptusAstartes ha scritto:

in ottica di ottenere performance migliori

Certo, fai bene a voler estrarre dal database solo i campi che ti servono. Comunque, anche se scegli Entity Framework, non sei obbligato ad usarlo in ogni situazione. Nei momenti in cui vuoi spremere il massimo delle prestazioni dai tuoi server, potresti addirittura leggere i dati con il DataReader di ADO.NET oppure usare un ORM molto più sottile come dapper. Dipende dalle criticità del tuo sistema. Le prestazioni non devono comunque essere un'ossessione, altrimenti rischieresti di sacrificare la tua produttività nell'opinabile obiettivo di risparmiare qualche millisecondo.

AdeptusAstartes ha scritto:

EF può darmi dei benefici oppure il grado di personalizzazione che voglio ottenere richia di portarmi a scrivere ancora buona parte del codice a mano con in più dei vincoli alla flessibilità?

Sì, può indubbiamente portarti dei benefici ma solo tu puoi decidere se iniziare ad impegarlo in questo progetto. L'investimento di tempo necessario a riscrivere funzionalità già implementate con l'altro ORM, potrebbe non essere completamente ripagato.
In particolare pensa alle necessità dei tuoi utenti. Stanno aspettando con urgenza nuove funzionalità? In questo caso diventa rischioso fermarsi e farli aspettare che tu abbia cambiato architettura.

Se invece hai già rilasciato una prima versione del software e sei in fase di analisi di una seconda versione, allora potresti avere l'opportunità per pianificare una nuova architettura.

ciao, spero di esserti stato d'aiuto.
Moreno

Enjoy learning and just keep making
37 messaggi dal 08 agosto 2008
Preziossimo!

Sono sempre più convito ad usare EF: pensandoci bene in effetti usare le SP per tutto è più abitudine che altro, così come accorparne le operazioni.

Ottima la dritta sull'interrogare direttamente gli oggetti e mi piace molto.

Dopotutto in questo progetto vorrei passare da una visione che privilegia il DB a una che privilegia il modello a oggetti e Ef mi aiuta ad entrare in questa ottica.

Penso che userò quindi i trigger per il logging sulle tabelle e demanderò il resto a EF.

Attualmente sono in fase di analisi e il primo passo che ho voluto fare è individuare il modo migliore per creare da zero una nuova applicazione senza preconcetti.

Dopo svariati giorni di studio vorrei adottare uno sviluppo guidato da questi pattern:
Domain driven design
Test Driven Development
MVVC
(Prism ma non ne sono sicuro, forse il progetto non è abbastanza complesso da meritarlo)

L'idea di fondo è usare questo progetto, piuttosto semplice, per apprendere queste tecniche di sviluppo.

Forse però è meglio che apro una nuova discussione in merito.
11.886 messaggi dal 09 febbraio 2002
Contributi
ciao,

AdeptusAstartes ha scritto:

Attualmente sono in fase di analisi

Ok, ottimo, allora è un buon momento per valutare le tecnologie da usare.

AdeptusAstartes ha scritto:

forse il progetto non è abbastanza complesso

Rivaluta attentamente se il Domain Driver Design è quello che ti serve. Non è propriamente un pattern architetturale ma un insieme di metodologie che ti aiutano ad affrontare un problema complesso e a scinderlo in parti discrete che possono comunque comunicare fra loro.

Il team di sviluppo dovrebbe sostenere la curva di apprendimento del DDD se il problema è abbastanza complesso da non poter essere affrontato agevolmente con altre metodologie.

Anche se non decidi di adottare completamente il DDD puoi comunque seguirne i concetti generali, come l'ubiquitous language, che promuove una uniformità di linguaggio in tutti gli ambiti, dai colloqui col committente fino al codice e alla documentazione.

Stai anche valutando anche il Test Driven Development, sarà sicuramente un'ottimo strumento che ti aiuterà a realizzare un prodotto di qualità.

ciao,
Moreno

Enjoy learning and just keep making
37 messaggi dal 08 agosto 2008

BrightSoul ha scritto:

Rivaluta attentamente se il Domain Driver Design è quello che ti serve. Non è propriamente un pattern architetturale ma un insieme di metodologie che ti aiutano ad affrontare un problema complesso e a scinderlo in parti discrete che possono comunque comunicare fra loro.

Il team di sviluppo dovrebbe sostenere la curva di apprendimento del DDD se il problema è abbastanza complesso da non poter essere affrontato agevolmente con altre metodologie.


Quello che mi interessa è il discorso partire modellando gli oggetti e non le tabelle e volevo proprio iniziare con questo progetto semplice (ci saranno si e no 10 entità principali).
Solo che sto già incontrando qualche difficoltà che ho scritto in un altro post...



Anche se non decidi di adottare completamente il DDD puoi comunque seguirne i concetti generali, come l'ubiquitous language, che promuove una uniformità di linguaggio in tutti gli ambiti, dai colloqui col committente fino al codice e alla documentazione.

Stai anche valutando anche il Test Driven Development, sarà sicuramente un'ottimo strumento che ti aiuterà a realizzare un prodotto di qualità.

ciao,
Moreno


Di metodologie e pattern ne sto guardando parecchi, il difficile sarà mettere tutto insieme:
DDD, TSS, inteface validation e fluent language nel domain layer
Entity framework con Unit of work, repository, Factory e Command query separation nel Data access layer
MVVM per l'interfaccia
Dependency injection non so ancora dove.

Mi voglio risparmiare giusto Prism e WCF per non complicarlo più di quanto non sia già...
Modificato da AdeptusAstartes il 12 agosto 2013 15.48 -
59 messaggi dal 17 maggio 2010
ciao,
Che tipo di applicazione vuoi fare? windows form o wpf? (o magari silverlight o asp.net)

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.