posts - 504, comments - 1656, trackbacks - 139

La rivolta contro i dataset

A poco più di un mese di distanza dal workshop “Data Management” dove ho evidenziato le debolezze del dataset per progetti consistenti, ecco apparire su MSDN un articolo intitolato “On the Way to Mastering ASP.NET: Introducing Custom Entity Classes”.

Quando nel summary ho letto le parole “There are situations for which untyped DataSets may not be the best solution for data manipulation” mi sono detto che mi suonavano molto familiari :-)

Naturalmente, essendo orientato ad asp.net l'articolo non tocca quegli aspetti che sono stati il culmine della mia sessione, in particolare (ma non solo) l'implementazione di IBindingList e ITypedList.

Resta comunque il fatto che il principio è lo stesso: il dataset come in-memory database è troppo povero per poter rappresentare adeguatamente un object model per una applicazione di media-alta complessità. Se poi vogliamo guardare alle performance i risultati sono sempre a favore delle custom entities come ho potuto mostrare durante la mia sessione con i risultati di un piccolo ma significativo benchmark.

Print | posted on martedì 5 aprile 2005 22.18 | Filed Under [ .NET [Italiano] ADO.NET [Italiano] ]

Feedback

Gravatar

# re: La rivolta contro i dataset

Disclaimer: sono un fan dei typed dataset
Non ho seguito il tuo workshop, vorrei capire se tu distingui la versione typed e untyped dei dataset.
Nei progetti in cui sono coinvolto solitamente l'80% del lavoro è portarsi in giro dei dati, eventualmente elaborarli e visualizzarli (browser).
Attualmente usiamo ADO, per cui recordset su cui lavoriamo ciclando con la movenext e accedendo alle colonne.
Dal mio punto di vista i typed dataset semplificano questo utilizzo, permettendo di avere anche le informazioni sulla struttura dei dati, permettendone la tipizzazione.

Dal mio punto di vista le feature di update/insert/delete sono marginali relative ad un sottoinsieme di quel 20% che rimane. Un sottoinsieme in quanto molte volte le modifiche vanno su insiemi limitati di dati (spesso un solo record) per cui l'approccio delle entity class va bene.

Il problema serio che stò vedendo con asp.net 2.0 è che, fino alla ctp di marzo, gestire i typed dataset è un incubo (creazione ottenuta tramite trucci, gestione connection string inutilizzabile, databinding che non usa la tipizzazione dei dataset)
06/04/2005 9.16 | Carlo Folini
Gravatar

# re: La rivolta contro i dataset

Carlo, peccato che non fossi presente e se sei presente Giovedi possiamo discutere durante una pausa di questo argomento.
I dataset li trovo molto indicati per progetti semplici laddove i dati possono essere strutturati in modo semplice.

Se guardo però ad un problema complesso, la prima cosa da fare è trovare un object model che rappresenti in modo adeguato il problema secondo i principi dell'OOP. In questo caso raramente riesco a rappresentare i problemi in modo tabulare (righe e colonne) e le datarelation mi vanno decisamente strette per stabilire il rapporto con i dati.

Preferisco quindi pensare ad un object model che soddisfi pienamente la logica del problema costruendo delle custom entities e delle collection che facciano da collante tra i vari oggetti.

Per questo motivo non faccio differenza tra typed e untyped. Certamente i typed dataset hanno molti vantaggi rispetto agli untyped ma soffrono comunque del problema descritto.

Se poi fai delle prove, vedrai che i dataset (proprio perchè generici) hanno un overhead che causa delle grosse perdite di performance che in alcuni casi (progetti medio-grandi per l'appunto) non sono da sottovalutare.

Purtroppo in qualche parola non si può descrivere tutto ma se ci sarai Giovedi potremmo chiaccherarne in una delle pause.

Ciao!
06/04/2005 9.58 | Raffaele Rialdi
Gravatar

# re: La rivolta contro i dataset

Purtroppo non sono riuscito ancora a trovare il tempo di metterci le mani seriamente per testarli.
Ho recentemente parlato con Balena e Dimauro e ho trovato lo stesso mio interesse nei dataset.
Sicuramente loro hanno fatto delle prove di carico, magari li sento e ci confrontiamo su questi argomenti.
Riesci a pubblicare il benchmark e i risultati?

Domani non sarò al workshop, comunque il fatto di scrivere su questi argomenti non mi dispiace in quanto mi permette di fare un po' di ordine ;-)

PS: ma lo human proof non si riesce proprio a sistemare/eliminare. Chi si può sentire per la sistemazione?
06/04/2005 10.55 | Carlo Folini
Gravatar

# re: La rivolta contro i dataset

So che Balena e Di Mauro "tifano" per i dataset. Ho avuto modo di parlarne soprattutto con Di Mauro che mi aveva detto in WPC che il motivo principale fosse l'eccesso di complessità nel costruire la collection che supportasse tutte le feature del dataset.

La difficoltà è infatti tanta e ma personalmente la ritengo di secondo piano perchè lo sforzo lo fai una volta sola. Io infatti mi sono creato un generatore di collection strong-typed che implementa tutte le interfacce necessarie a supportare le feature che sono esposte anche dal dataset.
Inoltre tieni conto che per il mondo asp.net le interfacce più complesse sono poco utili (IBindingList è praticamente inutile, mentre ITypedList può servire solo al design time).

Per semplicità la collection che ho mostrato nella mia sessione è stata sfoltita di alcune cose ma non è un task complesso completarla. Le cose più difficili sono nel codice che ho proposto in sessione.

I risultati del benchmark sono nelle mie slide e sono notevoli:
- Custom Entities 44secondi contro DataSet 1minuto e 9secondi
- I dataset impiegano il 57% del tempo in più rispetto alle custom entities
o se preferisci
- Le custom entities impiegano il 36% in meno rispetto al dataset

Per l'HIP devo chiedere ... anch'io ho problemi. Credo di sapere dov'è il problema.
06/04/2005 12.01 | Raffaele Rialdi
Gravatar

# re: La rivolta contro i dataset

ho trovato molto interessante il post è gli articoli segnalati, premetto che purtroppo non ero al WorkShop.
mi ha incuriosito nel tuo ultimo commento il generatore di collection strong-typed, puai darmi qualche delucidazione? sono molto curioso

ciao marco

p.s. inizia a dubitare della mia umanità visto che alla prima toppo sempre "Invalid Human Proof
"
06/04/2005 14.34 | marco
Gravatar

# re: La rivolta contro i dataset

Ciao Marco,
in una sessione di 1h15 non si può dire più di tanto e chi era presente credo possa dirti che ero al limite della "sopportabilità" ;-)

Sono un fan delle collection tipizzate e già ai tempi di COM ne ho costruita una in ATL (che faceva uso smodato di template annidati) proprio per costruire dei complessi object model tipizzati (si, sono un patito di strong-typing da sempre e ho sempre odiato il variant).

In dotnet le cose si sono semplificate tantissimo ma nonostante questo, ed in assenza (nella 1.1) dei generics, la fatica è ancora consistente se vuoi avere collection che supportino tutte le belle cose che fa il dataset (che è scritto splendidamente bene).

Una volta arrivato ad una collection che mi ha dato soddisfazione ho avuto ovviamente due esigenze:
- la necessità di replicare enne volte lo stesso codice per tutte le collection di cui avevo bisogno
- la necessità di poter rigenerare tutte le collection anche a progetto già in stato avanzato
A questo scopo mi sono scritto un tool che genera per ogni collection due classi: una astratta che fa il grosso, una concreta (che deriva dalla precedente) che non cambierà mai.
In questo modo ottengo di poter rigenerare quando voglio tutte le collection nel caso voglia modificare, fare un fix, o altro nelle collection. E d'altro canto quelle concrete conterranno invece le proprietà e i metodi delle collection specifici delle custom entities tipizzate.

Ovviamente in sessione non c'era tempo di parlare anche di questo e così ho semplificato il listato della collection e ho evitato di mostrare il tool.

Quando avrò più tempo preparerò altro materiale su questi argomenti e magari qualche articolo.

P.S. non sei l'unico non umano ;-)
06/04/2005 14.46 | Raffaele Rialdi
Gravatar

# re: La rivolta contro i dataset

Grazie mille, chiaro e completo come sempre :) per motivi di tempo mi trovvo spesso a utilizzare DataSet ma adesso che ho un pò di respiro mi guardavo in torno e il sistema che adotti e la tua soluzione mi è piaciuta davvero.

apettiamo un articolo per entrare nel dettaglio :)
06/04/2005 14.55 | marco
Gravatar

# re: La rivolta contro i dataset

Prego! Spero ci sia l'occasione dell'articolo ;-)
06/04/2005 17.12 | Raffaele Rialdi
Gravatar

# re: La rivolta contro i dataset

Nel caso di architetture 3 tier uno dei motivi che mi semplificano la vita con i Dataset è la serializzazione 'nativa' dei dataset. La comunicazione dei dati fra presentation e application la faccio con i webservices quindi il dataset viene serializzato automaticamente.
Per le collection come funziona? E' automatica o c'è da prevedre del codice di serializzazione? (nel caso si uso di remoting c'è anche la possibilità di serializzazione binaria....un giorno magari farò una verifica se si riesce ad usare la serializzazione binaria inserite in un webservice come, ad esempio, un base64?!?!)

Altra questione 'teorica' è l'orientamento SOA. Un webservice deve esporre il contratto all'esterno. Nel caso di typed dataset l'elemento di partenza è proprio un xsd che descrive i dati (che dò la parte di schema del contratto), per le collection bisogna inferire un xsd dal xml serializzato o c'è un meccanismo automatico?
Per correttezza devo dire che i guru del SOA direbbero che esporre un xsd di una struttura complessa e 'proprietaria' come i dataset è un po' barare ai 4 tenets.

Per quanto riguarda il databinding come si comportano le typed collection con, ad esempio, la gridview?
Devo dire cha il databinding dei dataset tipizzati in asp.net 2.0 è molto carente (per usare un eufemismo). Sembra strano che avendo tutte le informazioni sul tipo di dati da visualizzare non si riesca ad avere un supporto a design time decente. Probabilmente questo è legato ad un oggetto DataSetDataSource che è sparito nelle varie beta lasciandoci con il solo ObjectDataSource.
06/04/2005 17.38 | Carlo Folini
Gravatar

# re: La rivolta contro i dataset

Ciao Carlo,
nel caso di web services la differenza sta nel fatto che le custom entities devono essere presenti anche sul client. Per il resto sia custom entities che collection sono facilmente serializzabili e infatti le sto usando con remoting in modo più che soddisfacente sia con il formatter soap che binario.

Una precisazione è d'obbligo. I web services hanno senso solo se hai uno scenario che non è puro dotnet. Se invece tutti i client sono dotnet ha molto più senso remoting in quanto la ricchezza del contratto dotnet è di gran lunga superiore a quella wsdl che, proprio per offrire eterogeneità dei sistemi operativi dei client, deve essere più povera.

Concludendo la risposta è che si può anche con i WS. La mia collection internamente usa ArrayList e quindi viene serializzata questa ma se vuoi cambiare il modo in cui è rappresentata puoi farlo facilmente implementando ISerializable.

Tanto per darti un idea ecco una collection vuota di Customer serializzata con il formatter soap su file:

<SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:clr="http://schemas.microsoft.com/soap/encoding/clr/1.0" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<a1:CustomerCollection id="ref-1" xmlns:a1="http://schemas.microsoft.com/clr/nsassem/Test/Test%2C%20Version%3D1.0.1916.30593%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3Dnull">
<site xsi:null="1" />
<coll href="#ref-4" />
<_OnListChanged xsi:null="1" />
<_IsSorted>false</_IsSorted>
<_ListSortDirection>Ascending</_ListSortDirection>
</a1:CustomerCollection>
<a3:ArrayList id="ref-4" xmlns:a3="http://schemas.microsoft.com/clr/ns/System.Collections">
<_items href="#ref-5" />
<_size>0</_size>
<_version>0</_version>
</a3:ArrayList>
<SOAP-ENC:Array id="ref-5" SOAP-ENC:arrayType="xsd:anyType[16]" />
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
06/04/2005 19.08 | Raffaele Rialdi
Gravatar

# re: La rivolta contro i dataset

Ciao Raffaele,
non ero presente al workshop, ma ho seguito la discussione e ho letto le slides.
Premetto che anch'io non sono un sostenitore dell'accoppiata dataset-datatable (troppo generici e pesanti dal mio punto di vista), ma devo riconoscere che il secondo ha una funzione molto utile: la Select.
Come implementi questa caratteristica nelle custom collection tipizzate?
In particolar modo, come implementeresti i criteri di selezione?

Non mi pare che tocchi questo argomento nelle slides (spero, altrimenti sto facendo la figura dello scemo :-) )

Ciao
Roberto
08/04/2005 12.34 | Roberto
Gravatar

# re: La rivolta contro i dataset

Ciao Roberto, nelle collection che sto usando in un progetto ho già implementato dei filtri. Ho creato in sostanza un certo numero di metodi "SelectByxxx" che accettano dei parametri che sono ovviamente il criterio di filtro.
In questi metodi creo una nuova collection, itero quella già popolata (se stessa) alla ricerca di oggetti che rispondano al requisito e se c'è match li aggiungo alla nuova collection senza rimuoverli dall'altra.
In pratica ti trovi con due collection che collezionano gli stessi oggetti.
Questi metodi Select ritornano al chiamante la nuova istanza di collection filtrata.

Se il numero di oggetti è molto grosso (cosa che probabilmente non dovrebbe essere) puoi adottare due strategie:
- costruirti degli indici per eseguire delle ricerche in modo più veloce (un semplice array che contiene l'ordine degli elementi secondo un certo criterio)
- se una proprietà contiene campi molto grossi (stringhe lunghissime, blob o quant'altro) puoi conservare (esposti con "internal") gli hash di questi campi. Il confronto tra hash è più veloce e quando gli hash sono uguali verifichi anche i campi in modo da avere la certezza assoluta da aver trovato il campo giusto.

Poi ti puoi sbizzarrire con qualsiasi altra tecnica a seconda di come sono fatti le tue custom entity.
08/04/2005 18.15 | Raffaele Rialdi
Gravatar

# re: La rivolta contro i dataset

Ciao Raffaele,
quindi il criterio di ricerca è "cablato" nella firma del metodo:
Ad esempio
SelectByID
SelectByDesc
...
...
io pensavo ad implementare un generico Select che accetta come parametro l'istanza di una classe che espone un metodo che si occupa (quanti "che" :-))
di eseguire il confronto.... una specie di IComparator
Il problema è il dover implementare un Comparator diverso per ogni criterio ...

08/04/2005 19.01 | Roberto
Gravatar

# re: La rivolta contro i dataset

Ciao Roberto, generalizzare ha pregi ma anche difetti. Se hai effettivamente tanti metodi che sono analoghi per modalità di ricerca puoi fare anche come dici tu ma non è più strong-typed e puoi anche perdere in efficienza.
La soluzione più generica è ovviamente quella che usa reflection ma qui ovviamente hai le performance peggiori.
Se poi ci sono dei value type puoi avere la penalizzazione di box/unbox.
Devi valutare tu pregi e difetti... io preferisco avere tutto strong-typed.

(Qualcosa di meglio si potrà fare con i generics con il framework 2.0.)
08/04/2005 21.25 | Raffaele Rialdi

Post Comment

Title  
Name  
Email
Url
Comment   
Please add 2 and 8 and type the answer here:

Powered by: