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??!!!...
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
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
il primo suo che ricordo e ho e' su ado 'classic'.
ciao, a.