Newsgroup: it.comp.dotnet
Titolo: Punti comuni tra DataReader e DataTable

Ciao a tutti,
sto cercando qualche cosa che, a naso, dovrebbe essere difficile trovare, ma 
io ci provo ugualmente.
Quando ho una classe fortemente legata ad un database, all'interno della 
classe stessa c'e' sempre la presenza di una funzione ReadData che, tramite 
una query SQL, ottiene un DataReader a singola riga. Da questo DataReader, 
carico i dati, valorizzando le variabili locali della classe stessa.
Nella maggior parte dei casi, questa tecnica e' quella che preferisco.
Ci sono situazioni pero', ad esempio se mi serve una lista corposa di 
oggetti della classe in esempio, in cui l'utilizzo di un DataSet, e quindi 
di un DataTable, migliorerebbe di molto le prestazioni totali.
Vorrei pero' evitare di scrivere due metodi distinti di caricamento dati, 
uno per il DataReader, uno per il DataTable, ed a questo punto parte la 
domanda....
Esiste una interfaccia comune tra un DataReader e un DataTable (o, nel caso, 
un DataRow) ?
In fondo a me serve di leggere solo il contenuto della prprieta'  "Item" del 
DataReader o del DataRow.
Qualche idea?
Ah, solo per completezza di informazione, uso VB.Net 2008


se posso darti un consiglio, guarda gli ORM tra i quali Entity Framework 
mi pare finora svolga un egregio lavoro. Anch'io ero un fan di DataTable 
e DataReader ed ero titubante...ma una volta che 'assaggi' cosa vuol 
dire lavorare con delle 'pettinatissime' classi già modellate che 
rispecchiano il db e ti offrono dei semplicissimi metodi per le CRUD, la 
tecnologia precedente sembra preistoria!
Sander

 DataTable, migliorerebbe di molto le prestazioni totali.
falso, punto :-) resta col tuo bel DataReader.
.m
-- 
Mauro Servienti
{C67C0157-5D98-4733-A75E-93CAEE4BADC8}
Microsoft MVP - Visual C# / MCTS
http://mvp.support.microsoft.com
blog @ 
http://milestone.topics.it
whynot [ at ] topics [ dot ] it

 falso, punto :-) resta col tuo bel DataReader.
e a questo punto un "perché?" ci sta tutto! :-D
Ciao e buona giornata,
Giulio
-- 

 Giulio
.m


falso, punto :-) resta col tuo bel DataReader.
...
Mmm...
tenderei a fidarmi :-) pero' c'e' qualche cosa che non mi quadra, 
probabilmente utilizzo una tecnica errata per leggere i miei dati.
Provo a fare qualche esempio per spiegarmi meglio.
In una classe, ho una proprieta' ID, quando valorizzo questa proprieta', 
lancio una routine che "carica" i dati....
Public Property ID as Integer
    Set (byVal value as Integer)
        ' valorizzo la variabile locale
        ReadData
    End Set
    ' blocco Get
End Property
Private sub ReadData
    Dim DR as Datareader (bla bla)
End Sub
Adesso, ammettiamo che mi serva una lista di oggetti di questa classe; mi 
costruisco una query sql che mi restituisce una lista di ID in base ai 
parametri che mi servono, anche qui usando un DataReader, tipo:
Select ID from Tabella where *qualchecosa"
da questa query ottengo un DataReader, lo ciclo e memorizzo tutti gli ID 
ottenuti in una lista (ad esempio List (of Integer) ).
Una volta ottenuta la lista, devo ciclare ogni elemento della lista stessa, 
che non e' altro che un intero che rappresenta l'ID dell'oggetto, e per ogni 
elmento mi costruisco un oggetto andando poi a valorizzare la proprieta' ID 
dell'oggetto stesso, cioe':
For Each ID as Integer in lstID ' lstID, ovviamente e' la lista di integer
    Dim MioOggetto as New MiaClasse
    MioOggetto.ID = ID
    ' lo utlizzo o lo memorizzo in base a cio' che mi serve
Next
Da notare che ogni volta che chiudo un DataReader, chiudo automaticamente la 
connessione associata, dato che per default passo sempre 
CommandBehavior.CloseConnection come argomento al metodo ExecuteReader 
dell'oggetto SqlCommand... forse e' questo che mi fa perdere tempo?
Cio' che mi viene in mente, e che comunque provero' (Mauro, nun t'arrabbia', 
a Natale siamo tutti piu' buoni) e' che utilizzare una singola chiamata per 
costruire un DataSet e da quello estrarre una DataTable, e poi ciclare le 
righe della stessa, dovrebbe essere piu' veloce, nelle condizioni che ho 
descritto.
Chiaro che sulla lettura singola, e probabilmente anche di poche righe, il 
DataReader dovrebbe essere un bel po' piu' veloce.
Voi che ne dite?

 ottenuti in una lista (ad esempio List (of Integer) ).
che poi:
- Reflector alla mano, è la stessa strategia attuata dal metodo Fill del 
DataAdapter quando "riempie" un DataSet/DataTable
- è la stessa cosa che fa un O/RM (Entity Framework, Linq2SQL, 
NHibernate, ...) quando materializza una lista di oggetti
un consiglio: passa ad Entity Framework (più che altro a causa del Linq 
provider, che in NH purtroppo è ancora troppo acerbo) e vivi felice :-)
-- 
.A
GUISA - 
http://www.guisa.org
UGIdotNET - 
http://www.ugidotnet.org
Read my blog at: 
http://blogs.ugidotnet.org/pape

un consiglio: passa ad Entity Framework (più che altro a causa del Linq
provider, che in NH purtroppo è ancora troppo acerbo) e vivi felice :-)
...
Lo faro', ma non subito.
Purtroppo in produzione non abbiamo molto tempo per studiare e provare 
soluzioni nuove (solito annoso problema delle piccole realta'.. e forse da 
qualche anno anche di quelle piu' grandi).
Ho pero' iniziato a studiare da capo il C# 2008, un po' per il linguaggio in 
se, un po' per le novita' che ci sono state nel tempo fino al 2008... poi 
appena finito, passero' al 2010 ma nel frattempo sara' uscito 2015 ecc... e' 
tutto un rincorrere, ed in ritardo :-)
Oggi mi tocca della manutenzione su roba vb6 :-)


butto lï¿œ un paio di considerazioni:
1. in .net non c'ï¿œ nulla di piï¿œ efficiente (per la lettura) di un 
datareader. ï¿œ un cursore di tipo server, forward-only. Se usi un 
provider puro managed non hai neppure il performance hit 
dell'interoperabilitï¿œ verso codice nativo, di conseguenza ï¿œ il top.
2. La datatable non sa neppure cosa sia un database. ï¿œ un oggetto 
'generico' in memoria che viene riempito da un dataadapter (che usa un 
datareader. Come scrive Andrea nulla di piï¿œ di quello che fanno gli 
OR/M quando materializzano oggetti.
Ergo il paragone tra datareader e datatable non ï¿œ neppure fattibile
3. Datatable/dataset hanno grossi problemi di performance se non fai 
alcune operazioni vitali come la disabilitazione degli eventi durante 
il caricamento. In piï¿œ hai tonnellate di boxing/unboxing se i dati che 
metti nella datatable sono dei valuetype. Ergo le performance con la 
datatable sono tragiche in molti casi.
4. Se guardi 
rafcollection.codeplex.com
 trovi la mia collection che ha 
gli stessi vantaggi di una datatable ma senza gli hit di performance. 
Per farti un'idea leggi almeno il documento iniziale.
Nell'esempio (sempre pubblicato su codeplex) c'ï¿œ un sistema per fillare 
oggetti che usa in modo generico un datareader ma ti consente di 
gestire il mapping verso una tua classe in modo molto semplice.
ï¿œ di fatto un micro-or/m in cui il mapping ï¿œ fatto via codice. Diciamo 
un modo per avvicinarsi ali or/m veri.
5. Come giï¿œ scritto dagli altri, vai con EF4. Grazie all'ultimo feature 
pack 'code-first ctp5' non ï¿œ ancora il  paradiso, ma poco ci manca :)
-- 
Raffaele Rialdi
Microsoft .NET MVP 
http://mvp.support.microsoft.com
 -
http://italy.mvps.org
 UGIdotNET - User Group Italiano .NET
http://www.ugidotnet.org
 Weblog: 
http://blogs.ugidotnet.org/raffaele

 pack 'code-first ctp5' non ancora il  paradiso, ma poco ci manca :)
Paradiso del RAD vorrai dire... ;)
-LV

> Paradiso del RAD vorrai dire... ;)
Non necessariamente.
Personalmente uso la CTP5, nessun designer, ma solo le fluent api.


 Personalmente uso la CTP5, nessun designer, ma solo le fluent api.
Si', ma tu sei Raf... :)
-LV

5. Come già scritto dagli altri, vai con EF4. Grazie all'ultimo feature
pack 'code-first ctp5' non è ancora il  paradiso, ma poco ci manca :)
...
Ehhh...
sto ancora lontano da quella roba. Come ho detto piu' volte, qui si pretende 
che le cose funzionino dopo due ore dalla richiesta, non c'e' tempo per 
studiare cose nuove.
Per studiare e provare, lo devo fare solo soletto, a casa, quando ho tempo.
Tra i buoni propositi del 2011 c'e' anche il dedicare almeno un'ora, ma 
anche un'ora e mezza, 3 giorni alla settimana, allo studio di C#2008 con 
tutte le novita' (per me) che ci sono nel FW 3.5... vedremo qundo riusciremo 
a vedere il 4 :-)

 studiare cose nuove.
Ti capisco, ed e' ovviamente un problema alquanto diffuso. La mia
strategia in proposito e' comunque forzare sempre un po' verso il
nuovo: per esempio, passare a .Net 4, con annessi e connessi, non
necessariamente deve implicare che ne conosci a menadito tutte le
potenzialita': di sicuro da guardare le realease notes, per vedere le
principale differenze con la versione precedente (e quindi gli
eventuali problemi di compatibilita'/portabilita' rispetto a cio' che
gia' hai), ma poi le cose nuove uno le puo' vedere una alla volta, con
calma e via via che se ne presenta la necessita' o, ancora meglio,
l'opportunita'... In ogni caso, escono talmente tante cose a talmente
alta velocita' che pensare e tentare di padroneggiarle tutte piuttosto
comporta la paralisi...
La bottom line qui per me e' sempre ricordare che, poiche' compromesso
ci deve essere, allora sono i requisiti espliciti che vengono prima di
quelli impliciti.
My 2c,
-LV

 quelli impliciti.
da scolpire nella pietra ed esporre all'ingresso di ogni software house 
(e non solo)


 (e non solo)
Nell'ambito della dialettica problema/soluzione, non ti seguo... Il
RAD da solo basta forse oggi ed e' sicuramente un debito domani: il
compromesso, mi pare, e' tutto e solo li'.
-LV

 Nell'ambito della dialettica problema/soluzione, non ti seguo...
semplicemente, stavo affermando che condivido in toto la tua 
affermazione che avevo quotato, tutto qui


 oggetti
Essendo un cursore server il datareader non restituisce nulla di 
completo, come anche ha scritto Ludovico.
Tu apri la connessione, esegui la query, fai un ciclo sulla Read del 
datareader e nel finally chiudi il datareader e la connessione.
Al momento in cui fai la Read ottieni i dati di una riga e con questa 
crei l'oggetto corrispondente.
Se guardi l'esempio di codeplex che ti ho linkato trovi anche questa 
parte, resa opportunamente generica con tanto di gestione dei 
DBNull.Value (cioè i null del db che non corrispondono e non possono 
ovviamente corrispondere ai null di .net).


Tu apri la connessione, esegui la query, fai un ciclo sulla Read del
datareader e nel finally chiudi il datareader e la connessione.
...
Intendevo proprio questo, so bene che per la natura del DataReader non mi 
viene dato nulla in memoria, se non la riga corrente.
Grazie ancora a tutti e buon 2011! (non saro' l'unico che il 31 e' ancora al 
lavoro... vero?!?! )

 La mia
strategia in proposito e' comunque forzare sempre un po' verso il
nuovo: per esempio, passare a .Net 4, con annessi e connessi, non
necessariamente deve implicare che ne conosci a menadito tutte le
potenzialita'
....
Questa e' anche la mia strategia, ho dovuto insistere non poco per passare 
da VB6 a Net, pero' per giustificare una "perdita di tempo" (mooolto 
virgolettato) per apprendere un nuovo linguaggio o una nuova tecnica, devo 
far risaltare i vantaggi "visibili".
Sembrera' un assurdo, ma di manutenibilita', praticita' ecc.. fanno fatica a 
capire, ma il far vedere una listview "colorata", giustifica il passaggio a 
Net :-(


E' ovviamente un serio limite che nel nostro campo oggi sempre piu'
viga una sorta di... schizofrenia: uno scollamento fra la realta'
tecnologica e le aspettative del nostro committente interno, il quale
sempre piu' pensa di poterci "condurre" li' dove noi per primi
mostriamo poca solidita'.
Alcuni ulteriori consigli sparsi (al viandante che si trovi a
leggere):
1) certe distinzioni devono essere chiare a te e a nessun altro (non-
tecnico: i requisiti impliciti sono cio' di cui *non* si deve
discutere);
2) ne consegue che, se puoi farne a meno, *non* devi chiedere
autorizzazione su niente a nessuno: cio' che conta e' produrre il
risultato; e continuare a produrlo; (es. l'ultimo mio cliente era
ancora a ASP/VB/SQL2K: l'applicativo strategico l'ho fatto con VS2010
Express su SQL2008 Express su SVN: una favola... poi la fiducia
comunque era compromessa e me ne sono andato, ma chi mi ha sostituito
non ripartira' da ASP/VB... ho fatto bene o ho fatto male?)
3) i costi dell'apprendimento/aggiornamento non devono ricadere sul
committente: cioe', non ufficialmente/direttamente/esplicitamente...
piuttosto ricordagli sempre quanto e' scomodo il tuo sedile; (dopo
circa 20 anni di professione mi ritrovo una tendinite: usate i poggia-
polsi se davvero intendete fare questo mestiere;)
4) il nostro committente va preso... per la gola! Questo come minimo
significa che su certe cose fondamentali "o e' cosi' o niente". Oserei
dire che e' li' la principale differenza fra un principiante e un
esperto: nella capacita' di tirare quella linea.
Se uno consistentemente risolve problemi, la fiducia viene; e se poi
non viene (c'e' cliente e cliente), comunque non avrai perso il tuo
tempo...
D'altronde, e cosi' questo piccolo cerchio si chiude, construire
quella fiducia con buoni clienti e' uno di quegli skill da appendere
al muro, molto piu' importante della versione del framework in uso...
In bocca al lupo,
-LV

 End Sub
Quindi non separi DAL da BLL?

Quindi non separi DAL da BLL?
...
Beh, qui c'e' poco da separare... la mia classe deve saper leggere i propri 
dati dal DB, e credo che questo metodo sia il migliore.
Fare una classe separata per fare da parser? In questo caso mi sembra 
davvero una lungaggine... naturalmente IMHO :-)

3) i costi dell'apprendimento/aggiornamento non devono ricadere sul
committente
...
Dipende da cosa intendi per committente. Se intendi il cliente finale, hai 
perfettamente ragione, se intendi la mia azienda.. beh... qualche appunto lo 
farei.
In qualunque azienda, la formazione del personale e' una spesa a carico 
dell'azienda stessa. O sbaglio?
Che poi, io, armato di buona volonta' voglia studiare, migliorare ed 
imparare per conto mio , ci sta, ma non credo sia un obbligo.
Chiaro poi che se, invece di un dipendente, uno e' un libero professionista, 
tutto il discorso che ho fato cade a pezzi :-)

 quelli impliciti.
Ci potresti spendere due parole?
Grazie,
Giulio
-- 

 tempo per studiare cose nuove.
Dal basso della mia esperienza, posso dirti che questo è un pessimo 
approccio che porta sempre a soluzioni "fragili" e spesso di scarsa 
qualità. Inoltre - ma questo lo dovrebbero capire i tuoi "boss" - a 
lungo termine è una strategia antieconomica. Ovviamente non lo dico solo 
per rigirare il coltello nella piaga, sia chiaro. :-P
Ciao e tanti auguri per i toi buoni propositi per il 2011,
Giulio
-- 

Dal basso della mia esperienza, posso dirti che questo è un pessimo
approccio che porta sempre a soluzioni "fragili" e spesso di scarsa
qualità.
...
Come credo ormai si sia capito chiaramente, io sono assssssssolutamente 
d'accordo con quanto dici.
Il problema e' sempre il solito... chi mi paga non mi da la possibilita' di 
prendermi del tempo per approfondire, migliorare ecc.. il problema poi sara' 
principalmente il suo;  certo, anche io avro' difficolta' a crescere 
professionalmente, questo e' certo, ecco perche' comunque *voglio* studiare 
ancora. Ci mettero' un po' di tempo in piu', questo e' sicuro.
Grazie degli auguri, che naturalmente sono ricambiati :-)

 tutto il discorso che ho fato cade a pezzi :-)
E' uguale: mai come nel nostro mestiere, con il suo altissimo
contenuto professionale, vale la massima che siamo tutti imprenditori
di noi stessi...
-LV


Un po' di parole in questo thread ce le ho gia' spese: mi puoi
specificare un po' di piu' cosa ti interessa approfondire, o qual'e'
il dubbio, ecc.?
-LV

Ciao LV,

Dal basso della mia ignoranza (e soprattutto dal basso di uno che non ha 
una connessione internet dal 25 dicembre a causa di un guasto che la 
Telecom non ha voluto riparare :-)) ti chiedo di:
- spiegare cosa intendi per bottom line
- spiegare cosa intendi per requisiti espliciti/impliciti
Grazie,
Giulio
-- 

 - spiegare cosa intendi per requisiti espliciti/impliciti
In ingegneria informatica si distinguono i requisiti espliciti da
quelli impliciti:
-- I *requisiti espliciti* sono quelli che derivano da esigenze
(esplicite) del cliente: sulle funzionalita' desiderate, le
prestazioni attese, i livelli di interattivita'; ovviamente il cliente
parte da un'idea piu' o meno vaga, e sta al consulente informatico, in
qualita' di analista, di arrivare insieme al cliente ad una
comprensione adeguata del dominio del problema/soluzione;
:: se questi requisiti sono rispettati, il cliente e' soddisfatto.
-- I *requisiti impliciti* sono quelli che derivano da considerazioni
tecniche (implicite): sulla usabilita', la manutenibilita' (correzione
errori ma anche modifiche e estensioni), il riuso, ecc.; non e'
pensabile che il cliente debba o possa dare feedback a questo livello,
e sta al consulente informatico provvedere per un'adeguata
implementazione;
:: se questi requisiti non sono rispettati, il cliente e' molto
insoddisfatto.
Con il Quality Function Deployment (QFD, una tecnica sviluppata dalla
Mitsubishi negli anni '70) si aggiunge un terzo tipo di requisiti (i
primi due vengono chiamati requisiti normali e requisiti attesi):
-- I *requisiti straordinari* sono quelli che superano le attese del
cliente (per esempio in termini funzionali, ecc.);
:: se caratteristiche straordinarie sono presenti, il cliente e' molto
soddisfatto.
Ma con questo siamo gia' alla fantascienza... :)
Occorre un buon manuale di ingegneria informatica/del software per
fissare questi concetti.
-LV

Se il mio capo e' troppo fuori dal ragionevole, io lo mollo per altri
lidi. Non e' un consiglio, ma nemmeno ci sono scuse: la scelta di
fondo, di starci o non starci, e' tua e solo tua, e dovrebbe dipendere
da valutazioni non solo per l'immediato. [... e tutto il resto...]
...
Si si, ci sto lavorando su. Assolutamente d'accordo con quello che dici, ed 
infatti sto iniziando a guardarmi intorno.
Il problema e', credo sia comune a tutti, che non posso fare troppo lo 
schizzignoso. Ho comunque una casa da portare avanti :-)
In realta' ho fatto anche un colloquio con una azienda *decisamente* piu' 
organizzata, ed ero disposto anche a perderci dei soldi nell'immediato, 
proprio perche' comunque offrivano la possibilita' di crescere (corsi, studi 
e quant'altro).... Mi sa che pero', la mia richiesta economica era ancora 
troppo alta per loro (e non ho chiesto la luna), oppure non gli sono 
piaciuto.. boh.
In ogni caso avevo gia' dall'inizio preso la cosa come una piccola 
esperienza, anche per capire come si fa un colloquio "serio", dato che 
fin'ora non ne ho mai avuto bisogno (non che sia un raccomandato, ma ho 
sempre lavorato con persone che in qualche modo mi conoscevano e sapevano 
come lavoro).