Newsgroup: it.comp.lang.visual-basic
Titolo: [VB.net] Recupero dati con un datareader

Il problema ce l'ho con asp.net...ma ho provato...è lo stesso anche con 
vb.net
!(il problema non sta in web o windows form!)
Net.2.0
Ho un database in Access...una tabella Articoli->Commenti....che 
malauguratamente ha i campi data e ora come testo!
Ho fatto una query che mi calcola al volo alcuni campi trasformandoli....mi 
spara fuori gli articoli ordinati per data e ora ed i relativi commenti 
ordinati per data e ora
ecco un po di codice
Using DCon As New OleDbConnection(conn)
            'apre connessione
            DCon.Open()
            'Assurda query!
            Dim TestoComando As String = ""
            TestoComando = "SELECT Articoli.ID AS IDArt, 
DateSerial(Mid$([Articoli].[Data],1,4),Mid$([Articoli].[Data],5,2),Mid$([Articoli].[Data],7,2)) 
AS DataArticolo, 
TimeSerial(Mid([Articoli].[Ora],1,2),Mid([Articoli].[Ora],3,2),Mid([Articoli].[Ora],5,2)) 
AS OraArticolo, Articoli.Data, Articoli.Titolo, Articoli.Autore, Commenti.ID 
AS IDCommento, 
DateSerial(Mid$([Commenti].[Data],1,4),Mid$([Commenti].[Data],5,2),Mid$([Commenti].[Data],7,2)) 
AS DataCommento, 
TimeSerial(Mid([Commenti].[Ora],1,2),Mid([Commenti].[Ora],3,2),Mid([Commenti].[Ora],5,2)) 
AS OraCommento"
            TestoComando += " FROM Articoli INNER JOIN Commenti ON 
Articoli.ID = Commenti.IDArticolo"
            TestoComando += " ORDER BY 
DateSerial(Mid$([Articoli].[Data],1,4),Mid$([Articoli].[Data],5,2),Mid$([Articoli].[Data],7,2)), 
TimeSerial(Mid([Articoli].[Ora],1,2),Mid([Articoli].[Ora],3,2),Mid([Articoli].[Ora],5,2)), 
Articoli.Titolo, Articoli.Autore, 
DateSerial(Mid$([Commenti].[Data],1,4),Mid$([Commenti].[Data],5,2),Mid$([Commenti].[Data],7,2)), 
TimeSerial(Mid([Commenti].[Ora],1,2),Mid([Commenti].[Ora],3,2),Mid([Commenti].[Ora],5,2));"
            'crea comando
            Dim Comando As New OleDbCommand
            Comando.Connection = DCon
            Comando.CommandText = TestoComando
...fin qui...nulla di nuovo!
Ora mi viene il problema
NON VOGLIO usare il dataAdapter...i dati li voglio leggere...popolare una 
dataTable dentro un DataSet....perchè poi eventuali modifiche me le 
rifletterò a manina dovendo aggiornare 2 tabelle (Articoli e Commenti)
Quindi cosa faccio?
(DR è il datareader)
DR = Comando.ExecuteReader(CommandBehavior.KeyInfo)
questo perchè uso
(DS è il dataset)
DS.Tables.Add(DR.GetSchemaTable())
e poi in teoria uso un ciclo
While DR.Read
                'crea le righe della tabella
                With DS.Tables(0)
                    riga = .NewRow
                    Dim n As Integer = 0
                    Try
                        For n = 0 To .Columns.Count
                            riga(n) = DR(n)
                        Next
                    Catch ex As Exception
                        Response.Write("ERRORE <br>N=" & n & " <br>")
                        Response.Write("colonne " & .Columns.Count)
                        Response.End()
                    End Try
                    .Rows.Add(riga)
                End With
End While
            DR.Close()
...a parte il response.write sostituibile con un msgbox....
il codice si pianta per un casting di un int32 a timestamp al secondo 
passaggio
...faccio stampare la struttura...spippolo ...leggo....
Alla fine scopro che il problema è questo....
non è creata la struttura giusta della dataTable...anzi non è creata per 
niente!
il primo campo è un ID...e un int32 va bene...il secondo è una data...e mi 
fa una spernacchiata!
Il dr.getschematable non ha creato una beneamata fava della struttura della 
query!!!....perchè?
Perchè oledb non funziona?
Perchè è una query con campi calcolati?
Se mi devo mettere a fare la dataTable "manualmente" è veramente inutile sto 
Net!!!
Io vorrei che la struttura che mi spara la query...fosse riflessa in un 
datatable....in automatico...(come un view di SQLserver per 
intenderci!)...perchè la query potrebbe variare...e i campi restituiti 
variare....
L'utilità del datasource tanto decantata non è proprio questa? una 
collezione di datatable esistenti al limite solo in memoria??!!!...

 
vb.net
!(il problema non sta in web o windows form!)
zac
il sonno...mi fa incartare !
DS.Tables.Add(DR.GetSchemaTable())...in realtà mi costruisce una tabella che 
mi riporta come è fatta la mia query....
non mi costruisce automaticamente la dataTable!
Ditemi che è il sonno che mi fa sragionare e non devo ciclare questa tabella 
per costruirmi la mia dataTable!
va a finire che mi fa piacere l'obbrobrio del dataAdapter!...almeno li c'è 
il fill che fa tutto lui!
SOLO CHE a causa del sonno fai l'ultimo tentaivo...e 
funziona...funziona...funzionaaaaaa
grazie a quel sant'uomo di Francesco Balena!
e funziona addirittura su Aruba...pensa un po!
Balena giocando con quel tool di hacking che è il Reflection fa fare un Fill 
da un datareader!!!
http://www.dotnet2themax.it/ShowContent.aspx?ID=3c88d57d-c84c-44b9-b01b-0eedac2585eb
ecco come funziona tutto via web!
Private Sub InizializzaDB()
Dim conta As Integer
'Recupera la stringa di connessione da un file!
Try
Dim FileConf As New System.IO.StreamReader(Server.MapPath("netConnDB.cfg"))
conn = FileConf.ReadToEnd.Trim
FileConf.Close()
Catch ex As Exception
Response.Write("Errore connessione<br>")
Response.Write(Server.MapPath("\mdb-database\dblog.mdb"))
Response.End()
End Try
'pulisce dataset
DS.Tables.Clear()
'Usa la connessione al server

DR = Comando.ExecuteReader(CommandBehavior.KeyInfo)
FillDataSetFromReader(DS, "Commenti", DR)
DR.Close()
End Using
Me.GridView1.DataSource = DS
Me.GridView1.DataMember = "Commenti"
Me.GridView1.DataBind()
End Sub
....ecco la creazione di Balena....
Private Sub FillDataSetFromReader(ByVal ds As DataSet, ByVal table As 
String, ByVal dr As _
IDataReader)
' crea un xxxDataAdapter del medesimo tipo del DataReader
Dim drType As Type = CObj(dr).GetType
Dim typename As String = drType.FullName.Replace("DataReader", 
"DataAdapter")
Dim daType As Type = drType.Assembly.GetType(typename)
Dim da As Object = Activator.CreateInstance(daType)
' invoca il metodo protetto Fill
Dim args() As Object = {ds, table, dr, 0, 999999}
daType.InvokeMember("Fill", BindingFlags.InvokeMethod Or 
BindingFlags.NonPublic Or _
BindingFlags.Instance, Nothing, da, args)
' chiude il DataReader
dr.Close()
End Sub

 ha scritto nel messaggio 
news:48866e3a$0$17935$5fc...@news.tiscali.it...
è inutile stasera il sonno mi stimola
....
ho trovato un altra soluzione
....
DR = Comando.ExecuteReader(CommandBehavior.KeyInfo)
Dim miaTab As New DataTable
miaTab.TableName = "CommentiArt"
miaTab.Load(DR)
DR.Close()
DS.Tables.Add(miaTab)
il metodo Load accetta anche IDataReader...la velocità suppergiù è la 
stessa...ma non uso Reflection....e funziona anche sul web!
...ora vado a letto davvero!
E dire che era tutto il pomeriggio che ci sbattevo la testa  ....e vabbè!
notte notte! 


Ciao wodka,
questa è anche la soluzione consigliata da Sceppa (tra le tante) e la uso da
tempo, solo che alle 2 di notte dormivo, sennò ti avrei aiutato subito.
Immagino tu lo sappia già, ma è meglio pero' usare un bel using, cosi'
liberi le risorse subito. il datareader è una bestiaccia con le
connessioni..se ti scordi di chiuderlo, è un macello. Nota la dichiarazione
della tabella fuori da using, senno' il suo scope è limitato.
Dim miaTab As New DataTable("CommentiArt")
Using DR as datareader=Comando.ExecuteReader(CommandBehavior.KeyInfo)
        miaTab.Load(DR)
end using
DS.Tables.Add(miaTab)
semplice,conciso e veloce!
ciao Umbe

 da
.....
sarò ignorante....ho fatto la scansione dell'hard disk neuronale senza 
trovare dati.
....ma.....
chi cavolo è "Sceppa" ????? 

Wodka40 ha scritto:

david sceppa, ha scritto programmare 
ado.net
 2.0
saluti MVB

 chi cavolo è "Sceppa" ?????
http://www.google.it/search?q=sceppa+datareader&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:it:official&client=firefox-a
il primo suo che ricordo e ho e' su ado 'classic'.
ciao, a.