cippalippa371@virgilio.it Database ADO.NET per utenti ADO di VB6 Questo lavoro ha come scopo il facilitare la transizione degli utenti di VB6 a .NET che utilizzano database. Questo piccolo progetto mostra come si possa creare un database in .NET mantenendo le stesse funzionalita' che si hanno in VB6, con comandi simili a quelli gia' conosciuti nel precedente linguaggio. Ricordo ancora le difficolta' che ho avuto quando mi sono avvicinato a questa piattaforma per cercare dei punti di riferimento. Cercavo sui testi e trovavo argomenti incomprensibili e che non riucivo a rendere concreti. Chiedevo su Internet, non mi veniva risposto perche' le domande che facevo sembravano troppo banali. Dicevano che avrei dovuto studiare di piu'... Ho creato questo progetto per evitarvi le mortificazioni di non ottenere risposte quando vi troverete in difficolta' per gli argomenti piu' banali. Il livello di difficolta' e' previsto per i principianti, che troveranno un utile piattaforma per ampliare di funzionalita' una buona base di codice. L'oggetto che rende questo db cosi' simile a quello che ho creato per VB6, e che potete trovare a: http://forum.masterdrive.it/f35/data...474/#post89474 <http://forum.masterdrive.it/f35/database-ado-jet-per-principianti-17904-post89474/>, si chiama BINDINGSOURCE. Da non confondere con il DataBinding, che ha lo stesso nome del corrispondente in VB6 ma un comportamento completamente diverso. Per cominciare scriviamo la riga seguente tra le dichiarazioni generali Codice: Imports System.Data Oppure attiviamola da: Progetto/Aggiungi riferimento/(tab .NET)/ System.Data, (e' l'equivalente di attivare il riferimento ad ADO 2.X) Codice: Public Class Form1 'Dopo la dichiarazione della classe, crea una connessione, come in VB6: Dim con As New OleDb.OleDbConnection Dim sql As String 'La variabile che contiene la Query di selezione Dim ds As New DataSet Il DataSet, un oggetto che non esiste in VB6, che contiene la copia della tabella nel database Codice: Dim da As OleDb.OleDbDataAdapter Il DataAdapter e' il vettore che contiene le modifiche effettuate al record nel dataset e le sposta nel record del database, e viceversa. Questo e' l'oggetto magico che rende tutto cosi' semplice. Il BindingSource Nel Form_Load() Viene dichiarata la connessione, viene aperta e si scrive la query Codice: Dim bs As New BindingSource Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load con.ConnectionString = "PROVIDER=Microsoft.Jet.OLEDB.4.0;Data Source = Archivio.mdb" con.Open() sql = "SELECT * FROM Anagrafica" A questo punto, si crea il dataset. Un dataset puo' contenere piu' di una tabella al suo interno e le relazioni master/detail Quindi, si crea il DataAdapter (la spola...) Nella seconda riga viene usato per riempire il dataset con l'istruzione SQL Codice: ds = New DataSet("Anagrafica") da = New OleDb.OleDbDataAdapter(sql, con) da.Fill(ds, "Anagrafica") bs = New BindingSource() 'qui si crea la BindingSource... bs.DataSource = ds bs.DataMember = "Anagrafica" '...che si collega al dataset che contiene la nostra tabella Chiudo la connessione, lavoro su dati disconnessi Codice: con.Close() Questa e' una delle piu' grandi differenze tra ADO e ADO.NET Questo e' il binding diretto alle textbox Codice: TextBox1.DataBindings.Add("text", bs, "ID") TextBox2.DataBindings.Add("Text", bs, "Nome") TextBox3.DataBindings.Add("Text", bs, "Cognome") Questo e' il binding alla Combobox Notare che la datacombo non esiste piu'. Questo controllo unisce le funzionalita' di entrambe Codice: ComboBox1.DataSource = ds.Tables("Anagrafica") ComboBox1.DisplayMember = "Cognome" ComboBox1.ValueMember = "ID" Imposto la Proprieta' Text. Questa riga consente di visualizzare nel controllo il record corrente Codice: ComboBox1.DataBindings.Add("Text", bs, "Cognome") Adesso si collega la ListBox, vale lo stesso discorso per la datalist Notare che ha una riga di meno rispetto alla combobox. Questo perche' decido di NON usarla come strumento di selezione (per andare a un record), ma solo per visualizzare il record corrente. Codice: ListBox1.DataSource = ds.Tables("Anagrafica") ListBox1.DisplayMember = "Cognome" ListBox1.DataBindings.Add("Text", bs, "Cognome") Binding alla DataGridView Codice: DataGridView1.DataSource = bs NOTA BENE! Se il dataset contiene piu' di una tabella, e' necessario anche impostare una seconda riga Codice: DataGridView1.DataMember = "Anagrafica" Ma in questo caso non e' necessaria perche' si sta usando solo una tabella Questo e' il binding verso la checkbox Codice: CheckBox1.DataBindings.Add("Text", bs, "Validita") End Sub Muoversi nel DataSet La riga segnata in rosso, permette di muoversi nel dataset per andare al record selezionato nella combobox Notare che usa il metodo FIND, uguale ad ADO, inoltre i comandi di spostamento sono analoghi a quelli di VB6 Codice: Private Sub ComboBox1_SelectionChangeCommitted(ByVal sender As Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectionChangeCommitted bs.Position = bs.Find("ID", ComboBox1.SelectedItem(0)) End Sub La prima riga delimita una Region, che non ha corrispondenti in VB6, e' un blocco di codice, in questo caso per la NAVIGAZIONE Codice: #Region "Navigazione" Private Sub Primo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Primo.Click bs.MoveFirst() End Sub Private Sub Successivo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Successivo.Click bs.MoveNext() End Sub Private Sub Precedente_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Precedente.Click bs.MovePrevious() End Sub Private Sub Ultimo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Ultimo.Click bs.MoveLast() End Sub #End Region Finisce la region navigazione e comincia quella EDITAZIONE Editare il DataSet Come si puo' notare dalla riga in rosso, anche il comando di aggiunta di un record e' uguale a VB6. Codice: #Region "Editazione" Private Sub Nuovo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Nuovo.Click bs.AddNew() End Sub Private Sub Aggiorna_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Aggiorna.Click Qua invece e' un po' diverso. Dipende dalla diversa struttura di ADO.NET Il comando di seguito avverte ADO.NET che abbiamo finito di apportare modifiche al dataset Codice: bs.EndEdit() Viene creato un CommandBuilder, un oggetto che si incarica di creare una query ad hoc per aggiornare la tabella del database Codice: Dim cb As New OleDb.OleDbCommandBuilder(da) da.Update(ds, "Anagrafica") End Sub Il CommandBuilder agiorna la tabella. Il comando e' simile all'update di ADO... Pero' questo NON e' sufficiente, si deve togliere la riga anche dalla tabella nel database. Questo viene fatto con la terza riga, la seconda crea il solito commandbuilder Codice: Private Sub Elimina_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Elimina.Click bs.RemoveCurrent() 'Rimuove la riga corrente dalla tabella nel dataset Dim cb As New OleDb.OleDbCommandBuilder(da) da.Update(ds, "Anagrafica") End Sub #End Region Ricerche nel DataSet Per effettuare una ricerca si deve usare un filtro. La sintassi e' la stessa di ADO per VB6 Codice: #Region "RICERCA" Private Sub Cerca_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Cerca.Click bs.Filter = "Cognome = '" & TextBox4.Text & "'" End Sub Mentre per visualizzare di nuovo tutti i dati si deve usare questo comando Codice: Private Sub Mostra_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Mostra.Click bs.RemoveFilter() End Sub #End Region End Class Con questo si esaurisce il piccolo progetto che spero possa aiutarvi nell' upgrade di piattaforma Tengo a precisare una cosa: Se osserverete attentamente il comportamento della checkbox, vi accorgerete che NON cambia il segno di spunta allo scorrere dei record. Invece visualizza nell testo accanto alla casella lo stato del controllo (true/false). Dipende da questa riga: CheckBox1.DataBindings.Add("Text", bs, "Validita"), sostituendo "Text" con "Checked" assume il comportamento corretto, ma da' un errore alla creazione di ogni nuovo record. (Non viene visualizzato il record appena creato). Non sono risucito a risolverlo, e non so se dipenda da un bug specifico del programma, oppure da codice diverso da scrivere... Imports System.Data Oppure attiviamola da: Progetto/Aggiungi riferimento/(tab .NET)/ System.Data, (e' l'equivalente di attivare il riferimento ad ADO 2.X) Codice: Public Class Form1 'Dopo la dichiarazione della classe, crea una connessione, come in VB6: Dim con As New OleDb.OleDbConnection Dim sql As String 'La variabile che contiene la Query di selezione Dim ds As New DataSet Il DataSet, un oggetto che non esiste in VB6, che contiene la copia della tabella nel database Codice: Dim da As OleDb.OleDbDataAdapter Il DataAdapter e' il vettore che contiene le modifiche effettuate al record nel dataset e le sposta nel record del database, e viceversa. Questo e' l'oggetto magico che rende tutto cosi' semplice. Il BindingSource Nel Form_Load() Viene dichiarata la connessione, viene aperta e si scrive la query Codice: Dim bs As New BindingSource Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load con.ConnectionString = "PROVIDER=Microsoft.Jet.OLEDB.4.0;Data Source = Archivio.mdb" con.Open() sql = "SELECT * FROM Anagrafica" A questo punto, si crea il dataset. Un dataset puo' contenere piu' di una tabella al suo interno e le relazioni master/detail Quindi, si crea il DataAdapter (la spola...) Nella seconda riga viene usato per riempire il dataset con l'istruzione SQL Codice: ds = New DataSet("Anagrafica") da = New OleDb.OleDbDataAdapter(sql, con) da.Fill(ds, "Anagrafica") bs = New BindingSource() 'qui si crea la BindingSource... bs.DataSource = ds bs.DataMember = "Anagrafica" '...che si collega al dataset che contiene la nostra tabella Chiudo la connessione, lavoro su dati disconnessi Codice: con.Close() Questa e' una delle piu' grandi differenze tra ADO e ADO.NET Questo e' il binding diretto alle textbox Codice: TextBox1.DataBindings.Add("text", bs, "ID") TextBox2.DataBindings.Add("Text", bs, "Nome") TextBox3.DataBindings.Add("Text", bs, "Cognome") Questo e' il binding alla Combobox Notare che la datacombo non esiste piu'. Questo controllo unisce le funzionalita' di entrambe Codice: ComboBox1.DataSource = ds.Tables("Anagrafica") ComboBox1.DisplayMember = "Cognome" ComboBox1.ValueMember = "ID" Imposto la Proprieta' Text. Questa riga consente di visualizzare nel controllo il record corrente Codice: ComboBox1.DataBindings.Add("Text", bs, "Cognome") Adesso si collega la ListBox, vale lo stesso discorso per la datalist Notare che ha una riga di meno rispetto alla combobox. Questo perche' decido di NON usarla come strumento di selezione (per andare a un record), ma solo per visualizzare il record corrente. Codice: ListBox1.DataSource = ds.Tables("Anagrafica") ListBox1.DisplayMember = "Cognome" ListBox1.DataBindings.Add("Text", bs, "Cognome") Binding alla DataGridView Codice: DataGridView1.DataSource = bs NOTA BENE! Se il dataset contiene piu' di una tabella, e' necessario anche impostare una seconda riga Codice: DataGridView1.DataMember = "Anagrafica" Ma in questo caso non e' necessaria perche' si sta usando solo una tabella Questo e' il binding verso la checkbox Codice: CheckBox1.DataBindings.Add("Text", bs, "Validita") End Sub Muoversi nel DataSet La riga segnata in rosso, permette di muoversi nel dataset per andare al record selezionato nella combobox Notare che usa il metodo FIND, uguale ad ADO, inoltre i comandi di spostamento sono analoghi a quelli di VB6 Codice: Private Sub ComboBox1_SelectionChangeCommitted(ByVal sender As Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectionChangeCommitted bs.Position = bs.Find("ID", ComboBox1.SelectedItem(0)) End Sub La prima riga delimita una Region, che non ha corrispondenti in VB6, e' un blocco di codice, in questo caso per la NAVIGAZIONE Codice: #Region "Navigazione" Private Sub Primo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Primo.Click bs.MoveFirst() End Sub Private Sub Successivo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Successivo.Click bs.MoveNext() End Sub Private Sub Precedente_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Precedente.Click bs.MovePrevious() End Sub Private Sub Ultimo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Ultimo.Click bs.MoveLast() End Sub #End Region Finisce la region navigazione e comincia quella EDITAZIONE Editare il DataSet Come si puo' notare dalla riga in rosso, anche il comando di aggiunta di un record e' uguale a VB6. Codice: #Region "Editazione" Private Sub Nuovo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Nuovo.Click bs.AddNew() End Sub Private Sub Aggiorna_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Aggiorna.Click Qua invece e' un po' diverso. Dipende dalla diversa struttura di ADO.NET Il comando di seguito avverte ADO.NET che abbiamo finito di apportare modifiche al dataset Codice: bs.EndEdit() Viene creato un CommandBuilder, un oggetto che si incarica di creare una query ad hoc per aggiornare la tabella del database Codice: Dim cb As New OleDb.OleDbCommandBuilder(da) da.Update(ds, "Anagrafica") End Sub Il CommandBuilder agiorna la tabella. Il comando e' simile all'update di ADO... Pero' questo NON e' sufficiente, si deve togliere la riga anche dalla tabella nel database. Questo viene fatto con la terza riga, la seconda crea il solito commandbuilder Codice: Private Sub Elimina_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Elimina.Click bs.RemoveCurrent() 'Rimuove la riga corrente dalla tabella nel dataset Dim cb As New OleDb.OleDbCommandBuilder(da) da.Update(ds, "Anagrafica") End Sub #End Region Ricerche nel DataSet Per effettuare una ricerca si deve usare un filtro. La sintassi e' la stessa di ADO per VB6 Codice: #Region "RICERCA" Private Sub Cerca_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Cerca.Click bs.Filter = "Cognome = '" & TextBox4.Text & "'" End Sub Mentre per visualizzare di nuovo tutti i dati si deve usare questo comando Codice: Private Sub Mostra_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Mostra.Click bs.RemoveFilter() End Sub #End Region End Class |