!! database spiegato bene !!






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










( databasespiegatobene.html )- by Paolo Puglisi - Modifica del 17/12/2023