Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[VB.NET] Esecuzione immediata di una query

287 views
Skip to first unread message

Innuendo

unread,
Sep 13, 2010, 12:39:19 PM9/13/10
to
Ciao a tutti,
mi scuso per il subject poco chiaro, ma non sapevo come spiegarmi meglio.

Nel mio progetto ho una datagrid nella form principale (form1) che mi
mostra il contenuto di una certa tabella, poi ho un bottone che mi apre
una seconda form (form2) dove inserisco una nuova riga nella tabella
visualizzata nella datagrid.

Mi succede che quando premo "salva" nella form 2, nella form1 non vedo
la riga appena aggiunta, ma la vedo se aspetto circa un secondo.

Un codice come questo messo nella form1 non funziona

myfrmForm2.ShowDialog()
ricarica_datagrid()

Se invece faccio come nel codice seguente va tutto bene, ma non mi piace
l'effetto di "blocco" dell'applicazione per quel secondo e mezzo che
aspetto.

myfrmForm2.ShowDialog()
System.Threading.Thread.Sleep(1500)
ricarica_datagrid()

C'e' modo di "forzare" la scrittura del record sul db in modo da poter
utilizzare il primo pezzo di codice che ho scritto?

Sto utilizzando un db Accss via odbc.

Spero di essere stato abbastanza chiaro.

ciao e grazie
Mauro

Mauro Servienti [MVP]

unread,
Sep 13, 2010, 2:08:03 PM9/13/10
to
Ciao Innuendo,

You wrote on 13/09/2010 :
> Spero di essere stato abbastanza chiaro.

sei stato chiarissimo, ma quello che dici non ha senso :-) non è
possibile che il comportamento che rilesi si colpa della "query".
E' probabile, e sottolineo probabile, che sia un problema di
performance ma devi prima di tutto identificare il colpevole facendo un
po' di tracing, anche casalingo.

.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


Innuendo

unread,
Sep 13, 2010, 3:35:06 PM9/13/10
to
Il 13/09/2010 20.08, Mauro Servienti [MVP] ha scritto:
> sei stato chiarissimo, ma quello che dici non ha senso :-) non è
> possibile che il comportamento che rilesi si colpa della "query".
Mi puoi spiegare meglio?

Se io lancio la query e nella riga dopo chiudo la form e ricarico la
datagrid non vedo il valore appena inserito.
In access però lo vedo, rilancio la query che popola la datagrid e lo
vedo anche li, ma non se lo faccio immediatamente dopo il save.

Se introduco lo sleep di un secondo va tutto come mi aspetto ... perche'
tu dici che non è possibile che sia colpa della query?

Io pensavo che succedesse una cosa tipo:
1. la form2 lancia la query di update
2. nella riga successiva chiudo la form2
3. dalla form1 lancio la query che ri-popola la datagrid

se l'operazione 1 dura, poniamo, 5 millisecondi mentre la operazione 2
ne dura 1 soltanto, allora la operazione 3 viene lanciata prima che
venga completata la scrittura di update lanciata dalla operazione 1 e
quindi non vedo il record inserito.

> E' probabile, e sottolineo probabile, che sia un problema di performance
> ma devi prima di tutto identificare il colpevole facendo un po' di
> tracing, anche casalingo.

Come posso fare questo?

grazie per il tuo aiuto, ciao
Mauro

Mauro Servienti [MVP]

unread,
Sep 13, 2010, 11:28:48 PM9/13/10
to
Ciao Innuendo,

You wrote on 13/09/2010 :
> se l'operazione 1 dura, poniamo, 5 millisecondi mentre la operazione 2 ne
> dura 1 soltanto, allora la operazione 3 viene lanciata prima che venga
> completata la scrittura di update lanciata dalla operazione 1 e quindi non
> vedo il record inserito.

Non è possibile perchè l'unico scenario in cui lo sarebbe è quello
multi-threading ma se fossi in uno scenario multi-threading avresti
sicuramente gli strumenti per rimuovere la causa del problema.

>> E' probabile, e sottolineo probabile, che sia un problema di performance
>> ma devi prima di tutto identificare il colpevole facendo un po' di
>> tracing, anche casalingo.
> Come posso fare questo?

devi scroprire dove ti mangi quel "minuto", metti un po' di log prima e
dopo ogni funzione/metodo e traccia i tempi.

> grazie per il tuo aiuto, ciao

.m

Wodka40[Google]

unread,
Sep 14, 2010, 4:14:51 AM9/14/10
to
On 13 Set, 18:39, Innuendo <pr...@b.c> wrote:
se fosse stato in vb6 ti avrei detto "stacca la connessione riattacca
la connessione" ...in questo modo "forzi" tutto quello che c'è in
sospeso a essere scritto. E a riaggiornare la cache della griglia.

Ma in .net non so come "gira" l'ambarandan.
Ti consiglierei cmq:
1) Butta via ODBC e usa OLEDB (sopratutto con access ha poco senso)

2) Prova a non fidarti di data adapter e (per test)....fatti il tuo
comando SQL di aggiornamento....eseguilo(fatti un button che scatena
una scrittura e al limite una forzatura di aggiornamento della
griglia)....cambia nulla?

3) Aggiornare la griglia significa....riconnetersi al db...aspettare
che odbc si connetta....interrogare il db....ricevere i
dati...aggiornare dataset...aggiornare griglia! Và quanta roba

3a) Che cosa chiedi? Se sono 1000000 di record ovvio che un po
aspetti....sopratutto con il lentissimo ODBC....FILTRA!

3b) Come popoli la datatable?....non molto tempo fa uno sul ng
"ciclava" sul datareader!

3c) Hai problemi di rete? conflitti e quant'altro?

3d) Ma sei sicuro che non fai nulla? non hai qualche bug logico?
controlli che scattano...routine che si attivano?
Non è che hai una form "piena" e la ridisegni tutta e ti scattano
validazioni su altri controlli che ti fanno perdere tempo?

......prova...e facci sapere!

Innuendo

unread,
Sep 14, 2010, 10:26:36 AM9/14/10
to
Il 14/09/2010 10.14, Wodka40[Google] ha scritto:
> 1) Butta via ODBC e usa OLEDB (sopratutto con access ha poco senso)
Nell'immediato non posso, ma valuterò la cosa.

> 2) Prova a non fidarti di data adapter e (per test)....fatti il tuo
> comando SQL di aggiornamento....eseguilo(fatti un button che scatena
> una scrittura e al limite una forzatura di aggiornamento della
> griglia)....cambia nulla?

Non uso data adapter, il comando sql lo lancio già a manina, mi creo
l'sql e poi lo lancio con il comando query_update.
La form2 ha un pulsante "Salva" che esegue l'update e nella riga
successiva chiude la form (form.hide).

> 3) Aggiornare la griglia significa....riconnetersi al db...aspettare
> che odbc si connetta....interrogare il db....ricevere i
> dati...aggiornare dataset...aggiornare griglia! Và quanta roba

Si, lo so che è tutt'altro che ottimale, ma è una piccola applicazione
che mostra al massimo un centinaio di righe nella datagrid.
Ma se esiste un metodo migliore per farlo sono tutt'orecchi :-)

> 3b) Come popoli la datatable?....non molto tempo fa uno sul ng
> "ciclava" sul datareader!

Ho fatto una classe che usa il db per popolare diversi oggetti
(datagrid,array,lisbox, ...) con il risultato di una query, quello che
mi chiedi tu è questo spezzone di codice:

While Reader.Read()
dg.Rows.Add(1)
For i = 0 To (campi - 1)
dg.Item(i, riga).Value = Reader(i).ToString()
Next
riga += 1
End While
Reader.Close()


> 3c) Hai problemi di rete? conflitti e quant'altro?

No, il db si trova in locale sul pc su cui sviluppo, ho scelto odbc per
esplicita richiesta del committente che in futuro vuole mettere il db
"dove capita" ...

> 3d) Ma sei sicuro che non fai nulla? non hai qualche bug logico?
> controlli che scattano...routine che si attivano?
> Non è che hai una form "piena" e la ridisegni tutta e ti scattano
> validazioni su altri controlli che ti fanno perdere tempo?

Si, si, di questo sono discretamente sicuro. Posso provare a fare un
progetto minimale per riprodurre il problema e postarlo da qualche parte
se qualcuno vuole provare a riprodurlo.

ciao e grazie
Mauro

Wodka40[Google]

unread,
Sep 14, 2010, 11:37:55 AM9/14/10
to
On 14 Set, 16:26, Innuendo <pr...@b.c> wrote:
> Il 14/09/2010 10.14, Wodka40[Google] ha scritto:> 1) Butta via
zac

> While Reader.Read()
>      dg.Rows.Add(1)
>      For i = 0 To (campi - 1)
>          dg.Item(i, riga).Value = Reader(i).ToString()
>      Next
>      riga += 1
> End While
> Reader.Close()

........te sembra poco?

Fatti una query che ti riporta SOLO i dati che vuoi ....popola una
datatable ...agganciala alla griglia!
http://groups.google.it/group/it.comp.lang.visual-basic/browse_frm/thread/8d45b314a5866ceb/8795020f1f04d1fe?hl=it&lnk=gst&q=wodka40+datareader#8795020f1f04d1fe

un esempio
recupero dati da PostgreSQL (provider npgsql)
Public Function EseguiSQLasTable(ByVal TestoSQL As String,
Optional ByVal NomeTable As String = "TabPG1") As DataTable
'apri connessione
Using Conn As Npgsql.NpgsqlConnection = Connetti()
Using comando As New Npgsql.NpgsqlCommand
With comando
.CommandText = TestoSQL
.CommandType = CommandType.Text
.Connection = Conn
Dim miaTab As New DataTable(NomeTable)

Using DR As Npgsql.NpgsqlDataReader =
comando.ExecuteReader(CommandBehavior.KeyInfo)
miaTab.Load(DR)
DR.Close()
End Using
Return miaTab
End With
End Using
End Using


End Function

e l'uso in una form

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles Button1.Click
Dim mSQL As String
mSQL = "SELECT ""IDabbo"", ""IDstipulante"",
""IDbeneficiario"", ""FlagAbboTerzi"", " & _
"""DataInizio"", ""prezzoIniziale"", ""Durata"", ""Preavviso"",
""Posticipo""," & _
"""Nota"", ""TipoAbb"", ""AbboAttivo"", ""Pagamento"",
""Datamod"", ""Ute"" " & _
"FROM ""Abbonamenti"";"
myTAB = PSQL.EseguiSQLasTable(mSQL, "ABBO")

With myGrid
.AutoGenerateColumns = True
.DataSource = myTAB
End With
End Sub

A me non sembra lento.....anzi!...ovvio che qui si parla di db "a giro
per la rete"...e ci mette un po a connetersi la prima volta (npgsql è
comunque un prodotto open source con tutti i bastoni fra le ruote
possibili per "roba" non microsoft!)

p.s.
non guardare la query...in access si scrive diversa:senza virgolette!
Era solo per dimostarti che in un caso reale non mi sembra lento!

Innuendo

unread,
Sep 14, 2010, 1:32:47 PM9/14/10
to
Il 14/09/2010 17.37, Wodka40[Google] ha scritto:
> ........te sembra poco?

non l'ho capita :-(

Ho provato a fare come mi hai detto tu ma il problema rimane. ti copio
incollo il codice, sono poche righe, ho fatto un progettino di test ad hoc.

******
Questo è il codice della form1

Imports System.Data.Odbc

Public Class Form1
Public myfrm2 As New Form2

Public conn As New OdbcConnection
Public _reader As OdbcDataReader

Private Sub Form1_Load(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Me.Load
conn.ConnectionString = "dsn=SMTEST"
conn.Open()
dg()
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click

myfrm2.ShowDialog()
dg()
End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button2.Click
dg()
End Sub

Private Sub dg()
Dim cmd As New OdbcCommand("select * from operazioni", conn)
Dim miaTab As New DataTable("cippa")
Using DR As OdbcDataReader = cmd.ExecuteReader()
miaTab.Load(DR)
DR.Close()
End Using
With DataGridView1
.AutoGenerateColumns = True
.DataSource = miaTab
End With
End Sub
End Class


********
Questo quello della form2

Imports System.Data.Odbc

Public Class Form2
Private conn As New OdbcConnection
Private _reader As OdbcDataReader

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click

conn.ConnectionString = "dsn=SMTEST"
conn.Open()
Dim cmd As New OdbcCommand("insert into operazioni values
(999,'pippo','ATT')", conn)
_reader = cmd.ExecuteReader()
_reader.Close()
Me.Hide()
End Sub
End Class

ciao e grazie per l'aiuto
Mauro

Innuendo

unread,
Sep 14, 2010, 1:34:25 PM9/14/10
to
Il 14/09/2010 5.28, Mauro Servienti [MVP] ha scritto:
> devi scroprire dove ti mangi quel "minuto", metti un po' di log prima e
> dopo ogni funzione/metodo e traccia i tempi.

Premesso che sono davvero agli inizi con VB.NET, ho provato a cercare un
pò con google come tracciare il tempo di esecuzione delle funzioni ma
non ho trovato niente di "comprensibile" .... se puoi darmi una dritta
ti ringrazio.

ciao
Mauro

Mauro Servienti [MVP]

unread,
Sep 14, 2010, 3:06:31 PM9/14/10
to
Ciao Innuendo,

You wrote on 14/09/2010 :
> Il 14/09/2010 17.37, Wodka40[Google] ha scritto:
>> ........te sembra poco?
>
> non l'ho capita :-(
>
> Ho provato a fare come mi hai detto tu ma il problema rimane. ti copio
> incollo il codice, sono poche righe, ho fatto un progettino di test ad hoc.

prima di tracciare il codice facciamo un passo indietro perchè qui ci
sono una quantità notevole di problemi.

> ******
> Questo è il codice della form1
>
> Imports System.Data.Odbc
>
> Public Class Form1
> Public myfrm2 As New Form2
>
> Public conn As New OdbcConnection
> Public _reader As OdbcDataReader
>
> Private Sub Form1_Load(ByVal sender As Object, ByVal e As
> System.EventArgs) Handles Me.Load
> conn.ConnectionString = "dsn=SMTEST"
> conn.Open()

le connessioni sono risorse preziose e vanno create e parte il priù
tardi possibile, mai condivise/riciclate in questo modo.

> dg()
> End Sub
>
> Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
> System.EventArgs) Handles Button1.Click
> myfrm2.ShowDialog()
> dg()
> End Sub
>
> Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As
> System.EventArgs) Handles Button2.Click
> dg()
> End Sub
>
> Private Sub dg()
> Dim cmd As New OdbcCommand("select * from operazioni", conn)

non viene mai fatta la dispose del command, usa anche qui un blocco
using come fai per il datareader

idem come sopra stai sharando la connessione, inoltre perchè usi un
cursore forward only (il datareader) per fare una insert?
Usa cmd.ExecuteNonQuery().

> ciao e grazie per l'aiuto
> Mauro

.m

Innuendo

unread,
Sep 14, 2010, 3:52:23 PM9/14/10
to
Il 14/09/2010 21.06, Mauro Servienti [MVP] ha scritto:
> prima di tracciare il codice facciamo un passo indietro perchè qui ci
> sono una quantità notevole di problemi.
:-( lo immaginavo ....


> le connessioni sono risorse preziose e vanno create e parte il priù
> tardi possibile, mai condivise/riciclate in questo modo.

Io apro una connessione in ogni form, lo faccio in questo modo perchè
ogni form mi serve leggere dei dati dal db.
Quello che non so fare è fare la connessione solo nella form principale
e poi riutilizzare la stessa nelle form secondarie.

> idem come sopra stai sharando la connessione, inoltre perchè usi un
> cursore forward only (il datareader) per fare una insert?
> Usa cmd.ExecuteNonQuery().

Questo è un errore che ho fatto nel creare questo esempietto, nel
programma "vero" uso giustamente la ExecuteNonQuery.

Ma il fatto che anche in questo esempio banalissimo si presenti il
problema descritto ti dice qualcosa?

Qua non credo ci possano essere problemi di performance, possibile che
il problema che riscontro sia dovuto al mio modo barbaro di usare le
connessioni al db?

ciao, grazie
Mauro

Innuendo

unread,
Sep 14, 2010, 4:08:28 PM9/14/10
to
Il 14/09/2010 21.06, Mauro Servienti [MVP] ha scritto:
> prima di tracciare il codice facciamo un passo indietro perchè qui ci
> sono una quantità notevole di problemi.

Vediamo se riesco a migliorare le cose.
Ho sistemato la Form2 in questo modo, va bene?

Imports System.Data.Odbc

Public Class Form2


Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click

Using conn As New OdbcConnection
conn.ConnectionString = "dsn=SMTEST"
conn.Open()
Using cmd As New OdbcCommand("insert into operazioni values

(999,'pippo','ATT')", conn)

cmd.ExecuteNonQuery()
End Using
End Using


Me.Hide()
End Sub
End Class

ciao
Mauro

Innuendo

unread,
Sep 14, 2010, 4:12:55 PM9/14/10
to
Il 14/09/2010 21.06, Mauro Servienti [MVP] ha scritto:
> le connessioni sono risorse preziose e vanno create e parte il priù
> tardi possibile, mai condivise/riciclate in questo modo.

Scusa, riguardo a questo punto, cosa è meglio fare?

Io pensavo di aprire la connessione al db quando parte l'eseguibile e
poi mantenerla per tutta la durata di esecuzione del programma in modo
da non perdere tempo ad aprirla/chiuderla tante volte ... tu mi stai
suggerendo di fare il contrario?

Ovvero apro una connessione ogni volta che devo fare una query e poi la
chiudo appena fatta?

ciao
Mauro

Luca D

unread,
Sep 14, 2010, 7:52:06 PM9/14/10
to

Esattamente.

Quando dice che le connessioni sono "preziose" intende lato server;
meno tieni aperta una connessione, più il server (e il tuo programma
di conseguenza) scala meglio al crescere del carico.
Riapire la stessa identica connessione, in virtù di tutte le "malizie"
di ADO e dei DBMS, è estremamente veloce e non incide in maniera
apprezzabile sulle prestazioni del codice

Mauro Servienti [MVP]

unread,
Sep 14, 2010, 11:20:46 PM9/14/10
to
Ciao Innuendo,

You wrote on 14/09/2010 :
> Vediamo se riesco a migliorare le cose.
> Ho sistemato la Form2 in questo modo, va bene?
>
> Imports System.Data.Odbc
>
> Public Class Form2
> Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
> System.EventArgs) Handles Button1.Click
> Using conn As New OdbcConnection
> conn.ConnectionString = "dsn=SMTEST"
> conn.Open()
> Using cmd As New OdbcCommand("insert into operazioni values
> (999,'pippo','ATT')", conn)
> cmd.ExecuteNonQuery()
> End Using
> End Using
> Me.Hide()
> End Sub
> End Class

perfetto, è così che deve funzionare.

Innuendo

unread,
Sep 15, 2010, 12:30:19 AM9/15/10
to
Il 15/09/2010 5.20, Mauro Servienti [MVP] ha scritto:
> perfetto, è così che deve funzionare.

Ottimo, forse sto cominciando a capirci qualcosa !!! :-)
Grazie mille per la dritta sull'utilizzo di Using di cui nel manuale di
VB che sto usando non c'e' traccia.

Però questo non ha ancora risolto il problema dell'aggiornamento della
datagrid nella form principale :-(

ciao
Mauro

Innuendo

unread,
Sep 15, 2010, 12:31:52 AM9/15/10
to
Il 15/09/2010 1.52, Luca D ha scritto:
>> Ovvero apro una connessione ogni volta che devo fare una query e poi la
>> chiudo appena fatta?
>
> Esattamente.

Uao, ero convintissimo del contrario !

Poco male, per fortuna ho tutto quello che riguarda il db in una singola
classe che posso facilmente rivoluzionare per adottare questo comportamento.

grazie, ciao
Mauro

Mauro Servienti [MVP]

unread,
Sep 15, 2010, 2:20:02 AM9/15/10
to
Ciao Innuendo,

You wrote on 15/09/2010 :
> Però questo non ha ancora risolto il problema dell'aggiornamento della
> datagrid nella form principale :-(

giusto per capire... quanti record ci sono nella tabella?

Wodka40[Google]

unread,
Sep 15, 2010, 4:17:41 AM9/15/10
to
On 15 Set, 06:31, Innuendo <pr...@b.c> wrote:
> Il 15/09/2010 1.52, Luca D ha scritto:
logica disconnessa

Preparo la domanda
Apro una conn
chiedo
aspetto la risposta
chiudo la conn
gestisco la risposta

Meccanismi vari di connection pooling riutilizzano la connessione!

E' da ADO che si "dovrebbe" fare così!
Però c'era chi usava i cursori lato server e i recordset dinamici....e
allora si doveva mantenere una connessione continua!

In Ado.net è sparito questo meccanismo (che per piccole
applicazioni...nel senso di pochi utenti in una intranet... era
comodo: vedevi subito le modifiche . era come avere i vecchi terminali
connessi al "serverone" centrale)
Ado.net privilegia la logica "alla internet"....e giocoforza lavori
disconnesso (dovresti farlo)

In realtà io un pochetto "baro"
.....


Using comando As New Npgsql.NpgsqlCommand
With comando
.CommandText = TestoSQL
.CommandType = CommandType.Text
.Connection = Conn
Dim miaTab As New DataTable(NomeTable)


Using DR As Npgsql.NpgsqlDataReader =
comando.ExecuteReader(CommandBehavior.KeyInfo)
miaTab.Load(DR)
DR.Close()
End Using

......
Usando il command mi sparo una query nel server e con la risposta mi
faccio restituire una datatable....e poi stacco tutto!

probabilmente ti faceva fatica leggere
il codice che ti ho mandato....dove trovavi using
e anche il link alla precedente discussione su questo NG
dove un INESPERTO wodka40 chiedeva come mai doveva ciclare su tutto il
datareader per popolare qualcosa! e si incazzava con Microsoft perchè
tutto era lento!

Vabbeh...fai tu.....

Innuendo

unread,
Sep 15, 2010, 6:06:11 AM9/15/10
to
Il 15/09/2010 8.20, Mauro Servienti [MVP] ha scritto:
> giusto per capire... quanti record ci sono nella tabella?

Sono 61 righe, la tabella ha tre campi, un id, un nome e una sigla di
tre lettere.

Il codice è quello che ho già postato, visto che è piccolo lo ripropongo
con le correzioni fatte.

La form2 è dove eseguo la query di update:
Imports System.Data.Odbc

Public Class Form2
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Using conn As New OdbcConnection
conn.ConnectionString = "dsn=SMTEST"
conn.Open()
Using cmd As New OdbcCommand("insert into operazioni values
(999,'pippo','ATT')", conn)
cmd.ExecuteNonQuery()
End Using
End Using
Me.Hide()
End Sub
End Class


La form1 è dove ho la datagrid che viene aggiornata subito dopo aver
eseguito il codice della form2
Imports System.Data.Odbc

Public Class Form1


Public myfrm2 As New Form2
Public conn As New OdbcConnection

Private Sub Form1_Load(ByVal sender As Object, ByVal e As

System.EventArgs) Handles Me.Load
conn.ConnectionString = "dsn=SMTEST"
conn.Open()

dg()
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click

myfrm2.ShowDialog()
dg()
End Sub

Private Sub dg()
Using cmd As New OdbcCommand("select * from operazioni", conn)
Using miaTab As New DataTable("cippa")


Using DR As OdbcDataReader = cmd.ExecuteReader()
miaTab.Load(DR)
DR.Close()
End Using
With DataGridView1
.AutoGenerateColumns = True
.DataSource = miaTab
End With

End Using
End Using

Innuendo

unread,
Sep 15, 2010, 7:04:47 AM9/15/10
to
Il 15/09/2010 10.17, Wodka40[Google] ha scritto:
> probabilmente ti faceva fatica leggere
> il codice che ti ho mandato....dove trovavi using
> e anche il link alla precedente discussione su questo NG
> dove un INESPERTO wodka40 chiedeva come mai doveva ciclare su tutto il
> datareader per popolare qualcosa! e si incazzava con Microsoft perchč
> tutto era lento!

In effetti ho fatto un po' di fatica, perň adesso ho uno strumento in
piů che prima non conoscevo: Using :-) !!! Grazie !

Il tuo metodo purtroppo per me non č applicabile in quanto se uso quello
poi non posso aggiungere delle righe nella datagrid a runtime (cosa che
invece mi serve).

ciao
Mauro

Wodka40[Google]

unread,
Sep 15, 2010, 8:54:30 AM9/15/10
to
On 15 Set, 13:04, Innuendo <pr...@b.c> wrote:
> Il 15/09/2010 10.17, Wodka40[Google] ha scritto:
zac

> poi non posso aggiungere delle righe nella datagrid a runtime (cosa che
> invece mi serve).
>
> ciao
> Mauro
e qui sbagli!
Essendo disconnesso tu aggiungi le righe alla datatable che si
riflettono sulla griglia!
Poi....ribadisco POI...non avendo dataadapter....se ti pare aggiorni
il db "remoto"...altrimenti lasci tutto in memoria!

La griglia fa lo stesso implicitamente...tanto vale farlo
esplicitamente!

Non confondere il fatto che si chiama datatable con il fatto che un db
ha delle table!
la datatable è un oggetto che PUO' riflettere una tabella di un db. Ma
la posso costruire al volo con quello che voglio! Ad esempio con nomi
dei file e dimensione di una cartella!....non importa che rifletta un
db!

ad esempio....qui di db non c'è nulla!

Imports System.Data
Public Class Form1
Dim DT As DataTable
Private Sub GeneraGrid_Click(ByVal sender As System.Object, ByVal
e As System.EventArgs) Handles GeneraGrid.Click
DT = New DataTable("Test")
DT.Columns.Add("Nome", Type.GetType("System.String"))
DT.Columns.Add("Cognome", Type.GetType("System.String"))
DT.Columns.Add("Indirizzo", Type.GetType("System.String"))
DT.Columns.Add("Fatturato", Type.GetType("System.Decimal"))
'Inserisce dati nella tabella
Dim Riga As DataRow
'riga1
Riga = DT.NewRow
Riga("Nome") = "Pippo"
Riga("Cognome") = "De Pippis"
Riga("Indirizzo") = "Via platani 32"
Riga("Fatturato") = 12458.7
DT.Rows.Add(Riga)
'riga2
Riga = DT.NewRow
Riga("Nome") = "Paolino"
Riga("Cognome") = "Paperino"
Riga("Indirizzo") = "Via dei pisolini 12"
Riga("Fatturato") = 45852.25
DT.Rows.Add(Riga)
'riga3
Riga = DT.NewRow
Riga("Nome") = "Poldo"
Riga("Cognome") = "Sbaffini"
Riga("Indirizzo") = "Via Panini 54"
Riga("Fatturato") = 32450
DT.Rows.Add(Riga)
'aggancia alla griglia
Griglia.DataSource = DT
Griglia.AutoGenerateColumns = True
End Sub
End Class

....ho capito male???

Innuendo

unread,
Sep 15, 2010, 9:49:31 AM9/15/10
to
Il 15/09/2010 14.54, Wodka40[Google] ha scritto:
> Essendo disconnesso tu aggiungi le righe alla datatable che si
> riflettono sulla griglia!
Ah !!! Quindi invece di fare

datagrid.row.add()

come facevo io dovrei fare

datatable.row.add() // o come č la sintassi corretta

e me lo trovo istantaneamente nella datagrid a cui ho collegato la mia
datatable? Detta cosě mi pare semplicemente un passaggio in piů ...
forse mi sto perdendo qualche pezzo per strada.

Il mio metodo finora č:
faccio una query sul db, poi scorro il reader e aggiungo le righe (una
alla volta) alla mia datagrid. Una volta terminato questo l'utente da
interfaccia puň manipolare in diversi modi le righe della datagrid.
Quando ha terminato le sue operazioni io scorro le righe della datagrid
e aggiorno il db di conseguenza.

Il tuo metodo č:
faccio la query sul db, metto in una datatable il risultato del reader,
aggancio la datatable alla datagrid. Se l'utente vuole manipolare la
datagrid io faccio le manipolazioni sulla datatable e queste si
riflettono sulla datagrid.
Tutto giusto?

Intanto molte grazie per tutti questi input !!!

ciao
Mauro

Wodka40[Google]

unread,
Sep 15, 2010, 12:48:56 PM9/15/10
to
On 15 Set, 15:49, Innuendo <pr...@b.c> wrote:
> Il 15/09/2010 14.54, Wodka40[Google] ha scritto:>
zac
Tu prova a mettere quel codice in una form....non fai prima?
vedrai che se aggiungi una riga alla datagrid...la trovi nella
datatable...
il vantaggio è che fai un LOAD (io ripeto leggi quella vecchia
discussione) e carichi in un tempo risibile la datatable rispetto
all'assurdo ciclo : leggo aggiungo!
Ciclare il datareader lo fai perchè non hai un "fill".....ma (leggi la
vecchia discussione)
LOAD implemeta IDataReader...e puoi farti un load(datatable)!

Ovvio che la parte....dalla datatable al DB vero la devi gestire tu!
Ma questo lo fai comunque a quanto capisco!

Prova...
l'esperienza diretta vale più di mille parole!
;-)

Mauro Servienti [MVP]

unread,
Sep 15, 2010, 11:41:26 PM9/15/10
to
Ciao Innuendo,

You wrote on 15/09/2010 :
> Private Sub Form1_Load(ByVal sender As Object, ByVal e As
> System.EventArgs) Handles Me.Load
> conn.ConnectionString = "dsn=SMTEST"
> conn.Open()
> dg()
> End Sub

perchè la connessione su Form1 continua ad essere aperta subito e
sprecata?

Innuendo

unread,
Sep 16, 2010, 2:52:27 AM9/16/10
to
Il 16/09/2010 5.41, Mauro Servienti [MVP] ha scritto:
> perchè la connessione su Form1 continua ad essere aperta subito e sprecata?
Ehm .... non l'avevo ancora corretta .... :-(

Adesso funziona !!!

Ho fatto cosi:
Imports System.Data.Odbc

Public Class Form1
Public myfrm2 As New Form2

Private Sub Form1_Load ....
dg()
End Sub

Private Sub Button1_Click ...
myfrm2.ShowDialog()
dg()
End Sub

Private Sub dg()


Using conn As New OdbcConnection
conn.ConnectionString = "dsn=SMTEST"
conn.Open()

Using cmd As New OdbcCommand("select * from operazioni", conn)
Using miaTab As New DataTable("cippa")
Using DR As OdbcDataReader = cmd.ExecuteReader()
miaTab.Load(DR)
DR.Close()
End Using
With DataGridView1
.AutoGenerateColumns = True
.DataSource = miaTab
End With
End Using
End Using
End Using
End Sub
End Class


Ma giusto per curiosità ... cosa succedeva prima che non chiudevo la
connessione che aprivo nella form1?

Adesso grazie ai vostri consigli ho due nuove "best practice":
1. usare sempre using al posto di new (dove possibile)
2. aprire e chiudere la connessione al db prima e dopo ogni query

grazie !!!
ciao
Mauro

Innuendo

unread,
Sep 16, 2010, 2:56:36 AM9/16/10
to
Il 15/09/2010 18.48, Wodka40[Google] ha scritto:
> Tu prova a mettere quel codice in una form....non fai prima?
> vedrai che se aggiungi una riga alla datagrid...la trovi nella
> datatable...

Ma forse volevi dire il contrario ? Se io cerco di aggiungere una riga
alla datagrid mi dice che non posso perche' è collegata alla datatable,
questo l'ho già provato.


> l'esperienza diretta vale più di mille parole!

Si, certo, ci provo subitissimo!

Intanto già con la apertura e chiusura della connessione prima e dopo
ogni query ho risolto il problema per cui ho aperto il thread.

Adesso vedo di migliorare anche questo aspetto del programma, grazie
mille per tutti i consigli !

ciao
Mauro

Wodka40[Google]

unread,
Sep 16, 2010, 11:32:52 AM9/16/10
to
On 16 Set, 08:56, Innuendo <pr...@b.c> wrote:
> Il 15/09/2010 18.48, Wodka40[Google] ha scritto:
>
> > Tu prova a mettere quel codice in una form....non fai prima?
> > vedrai che se aggiungi una riga alla datagrid...la trovi nella
> > datatable...
>
> Ma forse volevi dire il contrario ? Se io cerco di aggiungere una riga
> alla datagrid mi dice che non posso perche' è collegata alla datatable,
> questo l'ho già provato.
no! lo fà!
Ovvio abilita dallo smarttag l'inserimento modifica cancellazione
della riga!...già che ci sei anche il riordino và! :)
Guarda il codice che ti ho postato l'ho scritto al volo....su un pc
con vs2010...e funziona!...vuoi vedere le schermate?

Innuendo

unread,
Sep 16, 2010, 12:16:09 PM9/16/10
to
Il 16/09/2010 17.32, Wodka40[Google] ha scritto:
>> Ma forse volevi dire il contrario ? Se io cerco di aggiungere una riga
>> alla datagrid mi dice che non posso perche' è collegata alla datatable,
>> questo l'ho già provato.
> no! lo fà!
> Ovvio abilita dallo smarttag l'inserimento modifica cancellazione
> della riga!...già che ci sei anche il riordino và! :)
> Guarda il codice che ti ho postato l'ho scritto al volo....su un pc
> con vs2010...e funziona!...vuoi vedere le schermate?

Ho provato, a me dice

"Impossibile aggiungere righe a livello di codice all'insieme di righe
di DataGridView in caso di associazione a dati del controllo."

Aggiungendo semplicemente questa riga al tuo codice
griglia.Rows.Add()

http://img816.imageshack.us/img816/2419/wodka.jpg

:-)


ciao
Mauro

Wodka40[Google]

unread,
Sep 17, 2010, 6:30:43 AM9/17/10
to
On 16 Set, 18:16, Innuendo <pr...@b.c> wrote:
zac

> Aggiungendo semplicemente questa riga al tuo codice
> griglia.Rows.Add()
>
> http://img816.imageshack.us/img816/2419/wodka.jpg
>
> :-)
>
> ciao
> Mauro

Wodka40 prende la mannaia diabolica di livello 24 potenziata con la
gemma di Arwatsu...si avvia a casa del troll Innuendo...spacca la
porta della tana protetta da incantesimi necromantici...sconfigge la
prima orda di Morgul verdi...lancia un incantesimo di protezione ed
affronta il golem rosso a difesa del sacello di Innuendo...la lotta si
protrae per molto tempo...alla fine la gemma di Arwatsu si attiva ed
imprigiona il potere del golem al suo interno....Wodka40 lancia un
incantesimo ristoratore...recuperate le forze entra nel sacello di
Innuendo e lo trascina sulla piazza del villaggio.
Wodka40 suona il corno di Gnargoz "lo schianta-lamer" e dal bosco
accorrono i sacri guerrieri Paramisha che circondano il troll Innuendo
scortandolo al patibolo installato nella piazza principale.
Il troll Innuendo viene incatenato alla colonna costruita in
Armagordolite che neutralizza qualsiasi incantesimo.
Wodka40 si avvicina al troll Innuendo e lo fissa negli occhi:
"Hai combattuto con onore...ma adesso è la fine!" sussurra.
"Dove ho sbagliato? dimmelo prima di raggiungere la sacre sponde di
Thanorin!" implora il troll
"Non hai usato il magico aiuto di F1...ne ti sei fatto aiutare dalla
poderosa magia di Intellisense 'colui che vede nel profondo'...."
risponde disgustato il paladino!
"E cosa avrei visto???" geme il troll
"Avresti visto come usare l'incantesimo ADD....ti sarebbe bastato fare
un ADD("")...." urla Wodka40 abbattendo la mannaia sul collo del troll
"noooooooooooooo.........."

**************************************
Game over
Power Up: 1700
Experience Point: 12500
Skillpoint : 34
Gold: 12900
Next level : 15 "Innuendos's Revenge"
**************************************

Wodka40[Google]

unread,
Sep 17, 2010, 6:39:34 AM9/17/10
to
On 17 Set, 12:30, "Wodka40[Google]" <virgultoamor...@latinmail.com>
wrote:
zac
Mancano le stats per Innuendo
> **************************************
> Game over
> Power Up: 100
> Experience Point: 1000
> Skillpoint : 12
> Gold: 500

> Next level : 15 "Innuendos's Revenge"
> **************************************
ITEMS:
MAGIC SCROLL

**************************************

DT.Rows.Add("")
DT.Rows.Add("")
DT.Rows.Add("")
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles Button1.Click
DT.Rows.Add("GASTONE", "PAPERONE", "VIA FORTUNELLI 12",
1236235.85)
End Sub
End Class

**************************************

Alla prossima partita!

Innuendo

unread,
Sep 17, 2010, 6:40:29 AM9/17/10
to
Il 17/09/2010 12.30, Wodka40[Google] ha scritto:

> "E cosa avrei visto???" geme il troll
> "Avresti visto come usare l'incantesimo ADD....ti sarebbe bastato fare
> un ADD("")...." urla Wodka40 abbattendo la mannaia sul collo del troll
> "noooooooooooooo.........."

[ ... ]
Un mega rotfl su tutta la prima parte :-) ... ma non darmi del troll o
del lamer :-(

Se tenti di aggiungere/modificare una riga nella datagrid quando hai un
datasource collegato NON funziona ... ci ho provato in tutti i modi.

Invece facendo le modifiche alla data table queste funzionano e si
propagano anche nella datagridview

> Next level : 15 "Innuendos's Revenge"

Con un magistrale colpo di PrintScreen poco prima di cadere Innuendo
riesce a dimostrare la sua innocenza :-)))

http://img440.imageshack.us/img440/7448/innuendorevenge.jpg

:-)

ciao
Mauro

Wodka40[Google]

unread,
Sep 17, 2010, 6:47:29 AM9/17/10
to
On 17 Set, 12:39, "Wodka40[Google]" <virgultoamor...@latinmail.com>
wrote:

> On 17 Set, 12:30, "Wodka40[Google]" <virgultoamor...@latinmail.com>
> wrote:
> zac
> Mancano le stats per Innuendo> **************************************
> > Game over
> > Power Up: 100
> > Experience Point: 1000
> > Skillpoint : 12
> > Gold: 500
> > Next level : 15 "Innuendos's Revenge"
> > **************************************
>
> ITEMS:
> MAGIC SCROLL

IMAGE FOR MAGIC SCROLL
http://www.martek.it/trick/esempiogrid.jpg

Wodka40[Google]

unread,
Sep 17, 2010, 6:59:16 AM9/17/10
to
On 17 Set, 12:40, Innuendo <pr...@b.c> wrote:
> Il 17/09/2010 12.30, Wodka40[Google] ha scritto:
ovvio che sei databound .....
ma è altrettando ovvio che non si capisce più una mazza di quello che
vuoi fare!

Aggiungere una riga

A) L'UTENTE si posiziona all'ultima riga imputa i campi e si sposta a
una nuova riga....lo fà!

B) IL PROGRAMMATORE vuole inserire una nuova riga.....lo inserisce
nella datatable e subito lo vede nella griglia (casomai pure
ordinato)....lo fà!

C) Vuoi una riga bianca? DT.Rows.Add("").....lo fà!

Quindi....l'utente ha a disposizione solo il metodo A....tu gli altri!

La griglia è l'interfaccia grafica...con tutte le facilitazioni del
caso!
Che ti cambia fare ADD sul datatable o sulla griglia?
Puoi formattarti le celle lo stesso come vuoi!
e hai anche chiarezza in più: da una parte i dati...da una parte la
rappresentazione grafica!

poi se i dati li vuoi riflettere sul db...o sui db...quello è un ALTRO
paio di maniche: sul client hai una datatable con i dati inseriti
dell'utente e una datagridview che li mostra.....cosa farne adesso di
questi dati è un altra cosa!

Innuendo

unread,
Sep 17, 2010, 7:02:56 AM9/17/10
to
Il 17/09/2010 12.39, Wodka40[Google] ha scritto:
> DT = New DataTable("Test")

[ ... ]

> 'aggancia alla griglia
> Griglia.DataSource = DT
> Griglia.AutoGenerateColumns = True
>
> DT.Rows.Add("")
> DT.Rows.Add("")
> DT.Rows.Add("")
> End Sub


Ma vedi che è come dicevo io allora? :-)

Tu stai aggiungendo la riga alla DataTable e NON alla DataGridView.

Il 15/09/2010 18.48, Wodka40[Google] ha scritto:
> Tu prova a mettere quel codice in una form....non fai prima?
> vedrai che se aggiungi una riga alla datagrid...la trovi nella
> datatable...

Prova ad aggiungere una riga alla DataGridView DOPO averci agganciato in
binding la tua datatable, vedrai che non è possibile fino a quando non
sganci la datasource.

Giusto?

ciao
Mauro

Innuendo

unread,
Sep 17, 2010, 7:16:52 AM9/17/10
to
Il 17/09/2010 12.59, Wodka40[Google] ha scritto:
> ma è altrettando ovvio che non si capisce più una mazza di quello che
> vuoi fare!

> B) IL PROGRAMMATORE vuole inserire una nuova riga.....lo inserisce


> nella datatable e subito lo vede nella griglia (casomai pure
> ordinato)....lo fà!

Ti chiedo scusa per il polverone sollevato.

Tutto è nato dal fatto che tu Il 15/09/2010 avevi scritto

> vedrai che se aggiungi una riga alla datagrid...la trovi nella
> datatable...

ovvero che aggiungendo una riga nella *datagrid* me la sarei ritrovata
nella datatable mentre è da fare il contrario come hai scritto
giustamente oggi qua sopra.

Aggiungi una riga alla *datatable* e te la ritrovi nella datagrid.

Avevo fatto quell'appunto più per chi in futuro sarebbe andato a leggere
il post, non volevo scatenare tutta questa (divertente) "battaglia" a
colpi di Arwatsu e Armagordolite :-)

Per il resto sono riuscito a fare quello che mi serviva, e adesso sono
alle prese con i report ... sarà un'altra lunga battaglia ...

grazie per tutto il tuo aiuto.

ciao
Mauro

Wodka40[Google]

unread,
Sep 17, 2010, 9:24:01 AM9/17/10
to
On 17 Set, 13:16, Innuendo <pr...@b.c> wrote:
> Il 17/09/2010 12.59, Wodka40[Google] ha scritto:
>
E' questione di intendersi....

LOGICAMENTE

Un utente aggiunge una riga alla griglia...perchè usa un interfaccia.
Un utente non è un programmatore ne è tenuto, per assurdo...(mica poi
tanto assurdo), a sapere nulla di pc! Usa una interfaccia!
Quindi in fondo alla griglia scrive qualcosa e quella riga viene
aggiunta!...modifica una cella e quella viene modificata!

Un programmatore no!
Se deve implementare l'aggiunta di dati a runtime....passa non
dall'interfaccia ma "spara" i dati direttamente dove serve!
Mi viene in mente:
Se avessi un button con "Importa CSV"....io leggo il file csv...mi
preparo i dati(controllo e quant'altro)...e poi NON vado di sendkeys a
simulare l'input di un utente!...i dati li aggiungo direttamente al
db...o alla datatable...o alla collezione...o al file...etc etc

Non mi sono "esplicitato" è vero...credevo di parlare con chi avesse
capito il concetto (e tu lo hai fatto ho capito)e non con un ignorante
totale (nel senso di digiuno di ogni nozione sull'argomento)!
E' colpa mia...dò per scontato di parlare con programmatori e non con
utenti!
Hai fatto bene a precisare questo mio errore!

Buono studio dei report

Wodka40[Google]

unread,
Sep 17, 2010, 1:18:20 PM9/17/10
to
On 17 Set, 13:16, Innuendo <pr...@b.c> wrote:
C'ho mille cose da fare e mi scordo....

SE...ripeto se....
volete MISCHIARE bound ed unbound...ad esempio per inserire colonne
con celle calcolate o numeri progressivi...o altro...

http://it.narkive.com/2008/12/11/2917502-vb-net-aggiungere-righe-e-valori-a-datagridview-popolato-con.html

....non mi ricordavo...questa discussione!!!
:oP

Mauro Servienti [MVP]

unread,
Sep 19, 2010, 5:45:25 AM9/19/10
to
Ciao Innuendo,

You wrote on 16/09/2010 :
> Ma giusto per curiosità ... cosa succedeva prima che non chiudevo la
> connessione che aprivo nella form1?
>
> Adesso grazie ai vostri consigli ho due nuove "best practice":
> 1. usare sempre using al posto di new (dove possibile)
> 2. aprire e chiudere la connessione al db prima e dopo ogni query

il problema non è nella connessione in se, piuttosto nel come ragiona
il GC (il Garbage Collector) quando incontra qualcosa che potrebbe
avere a che fare con il mondo unmanaged, come ad esempio una
"DbConnection". Ogni qual volta superi il boundary tra mondo managed e
mondo unmanaged è sempre consigliabile liberarsi il prima possibile
delle risorse unmanaged. Nel caso specifico dei database (quelli seri
ovviamente) la cosa in termini prestazionali è ininfluente perchè
esiste una cosa che si chiama connection pooling che ricicla le
connessioni, quindi nel tuo mondo managed apri e chiudi, ma in realtà
il dbms è smart, capisce che sei sempre tu, e ricicla garantendoti di
fatto il massimo delle performance.

0 new messages