DatReader e TableMapping

giovedì 04 dicembre 2008 - 16.05

Teech Profilo | Expert

Ho un DataTable tipizzato (creato da codice) che vorrei popolare, in base a vari metodi, con dei DataAdapter o dei DataReader. I nomi dei campi del DB NON corrispondono ai nomi dei DataColumns del DataTable tipizzato.
Usando i DataAdapter non ho problemi e tutto funziona correttamente avendo la possibilità di aggiungere al DataAdapter stesso un TableMapping.
Il problema ce l'ho utilizzando i DataReader... In poche parole, non viene restituito alcun errore, la proprietà Rows.Count del DataTable è inizializzata correttamente ma non riesco a "vedere" alcun dato: credo proprio per il fatto che non ho inserito alcun TableMapping al DataReader... Ma come posso fare questa operazione? Non capisco proprio...
Grazie!!!

--------------
Maurizio Brini
--------------
Nessuna impresa è mai stata compiuta da un uomo ragionevole

0v3rCl0ck Profilo | Guru

Ciao

>Ho un DataTable tipizzato (creato da codice) che vorrei popolare,
>in base a vari metodi, con dei DataAdapter o dei DataReader.
>I nomi dei campi del DB NON corrispondono ai nomi dei DataColumns
>del DataTable tipizzato.
>Usando i DataAdapter non ho problemi e tutto funziona correttamente
>avendo la possibilità di aggiungere al DataAdapter stesso un
>TableMapping.
>Il problema ce l'ho utilizzando i DataReader... In poche parole,
>non viene restituito alcun errore, la proprietà Rows.Count del
>DataTable è inizializzata correttamente ma non riesco a "vedere"
>alcun dato: credo proprio per il fatto che non ho inserito alcun
>TableMapping al DataReader... Ma come posso fare questa operazione?
>Non capisco proprio...
>Grazie!!!

Cosa intendi dire per "Il problema ce l'ho utilizzando i DataReader", intendi dire utilizzando il DataReader con il DataAdapter così: DataAdapter.Fill(DataTable, IDataReader) ?


-------------------------------------------------------------------
Michael Denny
Senior Software Developer - Microsoft Framework (C# ASP.NET VB.NET)
http://blogs.dotnethell.it/Regulator/

Teech Profilo | Expert

Il fatto è che uso o un DataReader o un DataAdapter: non ho istanziato il DataAdapter quando uso il DataReader....
Fondamentalmente il problema ce l'ho facendo
DataTable.Load(DataReader)
--------------
Maurizio Brini
--------------
Nessuna impresa è mai stata compiuta da un uomo ragionevole

0v3rCl0ck Profilo | Guru

>Il fatto è che uso o un DataReader o un DataAdapter: non ho istanziato
>il DataAdapter quando uso il DataReader....
>Fondamentalmente il problema ce l'ho facendo
>DataTable.Load(DataReader)

E perchè non usare il DataAdapter con il DataReader?


-------------------------------------------------------------------
Michael Denny
Senior Software Developer - Microsoft Framework (C# ASP.NET VB.NET)
http://blogs.dotnethell.it/Regulator/

Teech Profilo | Expert

Leggendo in giro ho capito che il DataReader è più performante del DataAdapter... Inoltre quando uso il DataReader è perchè i record mi servono in sola lettura, mentre quando uso il DataAdapter posso effettuare aggiornamenti ai dati...
Quello che faccio, fondamentalmente, e leggere dal DB e popolare un DataTable tipizzato così da implementare per ogni DataRow un'interfaccia... Questa interfaccia la uso nel costruttore delle classi specializzate per rendere sicura la creazione dell'oggetto.
Forse l'approccio è sbagliato, non saprei...

--------------
Maurizio Brini
--------------
Nessuna impresa è mai stata compiuta da un uomo ragionevole

0v3rCl0ck Profilo | Guru

>Leggendo in giro ho capito che il DataReader è più performante
>del DataAdapter... Inoltre quando uso il DataReader è perchè
>i record mi servono in sola lettura, mentre quando uso il DataAdapter
>posso effettuare aggiornamenti ai dati...

Si, diciamo che il DataAdapter fa effettivamente parecchi controlli, ha una complessità maggiore di quello che ti serve e di conseguenza è meno performante che una lettura diretta da DataReader.

Frammento della sola funzione di Fill del DataAdapter (che a sua volta chiama altre articolate funzioni):

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

Detto questo andiamo a vedere più da vicino la funzione .Load del DataTable, che uno potrebbe pensare sia sviluppata non utilizzando il DataAdapter:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

Invece da come si può vedere da quest'ultimo listato, la Load del DataTable utilizza un LoadAdapter per caricare i dati, a sua volta questo oggetto eredità da DataAdapter e la funzione FillFromReader, non fa altro che richiamare la funzione Fill del DataAdapter:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

>Quello che faccio, fondamentalmente, e leggere dal DB e popolare
>un DataTable tipizzato così da implementare per ogni DataRow
>un'interfaccia... Questa interfaccia la uso nel costruttore delle
>classi specializzate per rendere sicura la creazione dell'oggetto.
>Forse l'approccio è sbagliato, non saprei...

Visto bene come funzionano all'interno i due metodi (DataAdapter.Fill e DataTable.Load), possiamo, a mio avviso, tranquillamente spostarci su una soluzione custom. Senza helper di alcun tipo, andremo a riempire il DataTable semplicemente ciclando il DataReader con la funzione .Read, e con poche righe di codice, riuscirai anche a mappare in maniera custom, le colonne con nomi differenti.

while (reader.Read()) { dt["col1"] = reader["pippo"]; dt["col2"] = reader["pluto"]; dt["col3"] = reader["paperino"]; }

In questo modo eviti sicuramente di utilizzare il DataAdapter, e tra l'altro non ci vogliono poi così tante righe di codice. Potresti anche farti una funzione che dato il Reader, è un Dictionary di stringhe (o hashtable), dove la chiave sarebbe il nome della colonna di destinazione del datatable, e il value il nome della colonna sorgente dal datareader, in questo modo potresti fare una cosa del genere:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

Ovviamente questo è solo un esempietto e può e deve essere ancora sviluppato. Ad esempio li si basa solo sul tableMappings, ma se non dovesse esistere la colonna nel datareader darebbe eccezione, potrebbe andare bene anche così, dipende da come uno lo vuole strutturare.

Spero di esserti stato utile.

-------------------------------------------------------------------
Michael Denny
Senior Software Developer - Microsoft Framework (C# ASP.NET VB.NET)
http://blogs.dotnethell.it/Regulator/

Teech Profilo | Expert

Ehm... Non potevo sperare in una risposta più chiara, esaustiva e risolutiva

In questo modo posso anche inserire il TableMapping direttamente nella classe DataTable e se il mapping non corrisponde generare un'eccezione... Lavoro con dei Datareader ovviamente non tipizzati in una mia classe "Adapter" per il popolamento ed in fase di "tipizzazione" intercetto le eventuali incongruenze: in questo modo riesco ad aggiungere un ulteriore livello di incapsulamento alla procedura!!! E' la soluzione che cercavo ma non riuscivo a concretizzare...

Mi piace capire le cose e farle solo se le capisco e direi che sei stato più che chiaro!!!
Grazie mille, veramente utile il tuo consiglio!!!
--------------
Maurizio Brini
--------------
Nessuna impresa è mai stata compiuta da un uomo ragionevole

0v3rCl0ck Profilo | Guru

>Ehm... Non potevo sperare in una risposta più chiara, esaustiva
>e risolutiva
>
>In questo modo posso anche inserire il TableMapping direttamente
>nella classe DataTable e se il mapping non corrisponde generare
>un'eccezione... Lavoro con dei Datareader ovviamente non tipizzati
>in una mia classe "Adapter" per il popolamento ed in fase di
>"tipizzazione" intercetto le eventuali incongruenze: in questo
>modo riesco ad aggiungere un ulteriore livello di incapsulamento
>alla procedura!!! E' la soluzione che cercavo ma non riuscivo
>a concretizzare...

Si vero, hai ragione, puoi direttamente utilizzare il TableMappings del DataTable, e farti una sorta di tuo Adapter più soft e custom

>
>Mi piace capire le cose e farle solo se le capisco e direi che
>sei stato più che chiaro!!!
>Grazie mille, veramente utile il tuo consiglio!!!

Bene, sono contento di esserti stato di aiuto, e vedo che hai capito il tutto, perfetto

Alla prossima
Ciao
-------------------------------------------------------------------
Michael Denny
Senior Software Developer - Microsoft Framework (C# ASP.NET VB.NET)
http://blogs.dotnethell.it/Regulator/
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5