Il DataSet
Questo articolo propone lo stesso esempio dell'articolo precedente, ma lo
realizza con l'impiego degli oggetti DataSet e DataAdapter.
Il codice che presentiamo ha il compito di gestire un menu, su console, che
permette di eseguire operazioni base sul database Access articoli.mdb che
ora vi illustro:
Struttura tabella articoli |
Campo |
Tipo di dato |
id |
Contatore |
articoli |
Testo |
quantita |
Numerico |
La tabella "articoli" memorizzera' degli articoli da vendere e la loro
quantita'. Le operazioni disponibili nel nostro menu sono: Lista, Inserimento,
Modifica e Cancellazione.
Il DataSet viene riempito dai record forniti dalla query e li ospita, al
suo interno, in tabelle rappresentate da oggetti DataTable. Su queste
tabelle possiamo compiere tutte le operazioni che vogliamo, le modifiche non
verranno riflettute sul database stesso fintanto che non lo richiediamo
esplicitamente, eseguendo il metodo Update del DataAdapter che
associamo al DataSet. La classe Database racchiude questa
operazione nel metodo AggiornaDatabase. Quindi, dopo ogni inserimento,
modifica ed eliminazione, aggiorniamo subito il database. Avremmo potuto farlo
anche soltanto al termine del programma, dipende dalle esigenze.
Imports System.Data
Imports System.Data.OleDb
Module Module1
Private Sub StampaMenu()
System.Console.WriteLine()
System.Console.WriteLine("1 - Lista articoli")
System.Console.WriteLine("2 - Inserisci articolo")
System.Console.WriteLine("3 - Modifica quantita'")
System.Console.WriteLine("4 - Elimina articolo")
System.Console.WriteLine("5 - Esci")
System.Console.Write("Scegli: ")
End Sub
Sub Main()
Dim bEnd As Boolean = False
Dim op As String
Dim db As New Database()
db.sConnection = "Provider=Microsoft.Jet.OLEDB.4.0;"
db.sConnection = db.sConnection & "Data Source=..\articoli.mdb;"
db.CaricaDataSet()
While Not bEnd
StampaMenu()
op = System.Console.ReadLine()
Select Case op
Case "1"
db.ListaArticoli()
Case "2"
Dim art As String, qty As String
System.Console.Write("Articolo: ")
art = System.Console.ReadLine()
System.Console.Write("Quantita': ")
qty = System.Console.ReadLine()
db.Inserimento(art, qty)
db.AggiornaDatabase()
Case "3"
Dim id As String, qty As String
System.Console.Write("indice: ")
id = System.Console.ReadLine()
System.Console.Write("Quantita': ")
qty = System.Console.ReadLine()
db.Modifica(id, qty)
db.AggiornaDatabase()
Case "4"
Dim id As String
System.Console.Write("indice: ")
id = System.Console.ReadLine()
db.Eliminazione(id)
db.AggiornaDatabase()
Case "5"
bEnd = True
End Select
End While
End Sub
La parte di codice che segue, rimane sostanzialmente uguale a quella
dell'articolo precedente. Abbiamo soltanto aggiunto il DataSet
Class Database
Public sConnection As String
Private objConn As OleDb.OleDbConnection
Private objDataSet As DataSet
Sub New()
sConnection = ""
objConn = Nothing
objDataSet = Nothing
End Sub
Private Sub Open()
Try
objConn = New OleDbConnection(sConnection)
objConn.Open()
Catch e As Exception
System.Console.WriteLine(e.Message)
End Try
End Sub
Private Sub Close()
objConn.Close()
objConn.Dispose()
objConn = Nothing
End Sub
CaricaDataSet si occupa di riempire il DataSet con il risultato
della query. E' il DataAdapter che lo riempie, facendo da tramite con
il database. Al DataAdapter passiamo la query e la connessione. Il
metodo Fill riempira' il DataSet che gli forniamo come parametro.
Specifichiamo anche con quale nome identificare la tabella che il DataAdapter
creera'. Il DataSet, infatti, puo' contenere piu' tabelle contemporaneamente.
Quando il DataAdapter crea la tabella e' probabile che non sappia quale sia la
relativa struttura nel database, cioe' lo schema. In questo caso gli imponiamo
di reperirlo impostando la proprieta' MissingSchemaAction a AddWithKey,
questo, tra l'altro, infomera' la tabella anche su quale colonna/e sara' la
chiave primaria.
Public Sub CaricaDataSet()
Dim objDataAdapter As OleDbDataAdapter
If objDataSet Is Nothing Then objDataSet = New DataSet()
Try
Open()
Dim sQuery As String = "select * from articoli"
objDataAdapter = New OleDbDataAdapter(sQuery, objConn)
objDataAdapter.MissingSchemaAction = _
MissingSchemaAction.AddWithKey
objDataAdapter.Fill(objDataSet, "articoli")
Catch e As Exception
System.Console.WriteLine(e.Message)
End Try
Close()
End Sub
Nonostante il prossimo metodo sia abbastanza lungo, aggiornare il database con
il DataAdapter non e' complicato. Concettualmente, basta tener presente
che le modifiche verranno eseguite in base a comandi specificati da noi.
Esistono tre classi di comandi SQL che modificano il database, ed il
DataAdapter si basera' proprio su questi. Spetta a noi fornirglieli
utilizzando le tre proprieta': InsertCommand, DeleteCommand
e UpdateCommand. A queste proprieta' corrispondono degli oggetti
Command che creeremo come al solito. I comandi sono ovviamente parametrizzati
per indicare come operare sui record. Per ogni parametro specificheremo:
la colonna interessata, SourceColumn e dove prendere il valore,
SourceVersion. Un record con "version" Current indica, ad
esempio, il suo valore attuale, Original indica il valore originario
prima della modifica etc. Vedere l'enumerazione DataRowVersion.
Public Sub AggiornaDatabase()
If objDataSet Is Nothing Then Exit Sub
Dim objDataAdapter As OleDbDataAdapter
Try
Open()
Dim sQuery As String = "select * from articoli"
Dim sInsert As String = "insert into articoli " & _
"(articoli, quantita) values (?, ?)"
Dim sDelete As String = "delete from articoli where id = ?"
Dim sUpdate As String = "update articoli " & _
"set quantita = ? where id = ?"
Dim objInsertCmd As New OleDbCommand(sInsert, objConn)
Dim objDeleteCmd As New OleDbCommand(sDelete, objConn)
Dim objUpdateCmd As New OleDbCommand(supdate, objConn)
Dim objParam As OleDbParameter
' Insert
objParam = objInsertCmd.Parameters.Add("@art", _
OleDbType.Char)
objParam.SourceColumn = "articoli"
objParam.SourceVersion = DataRowVersion.Current
objParam = objInsertCmd.Parameters.Add("@qty", _
OleDbType.Numeric)
objParam.SourceColumn = "quantita"
objParam.SourceVersion = DataRowVersion.Current
' Delete
objParam = objDeleteCmd.Parameters.Add("@id", _
OleDbType.Numeric)
objParam.SourceColumn = "id"
objParam.SourceVersion = DataRowVersion.Original
' Update
objParam = objUpdateCmd.Parameters.Add("@qty", _
OleDbType.Numeric)
objParam.SourceColumn = "quantita"
objParam.SourceVersion = DataRowVersion.Current
objParam = objUpdateCmd.Parameters.Add("@id", _
OleDbType.Numeric)
objParam.SourceColumn = "id"
objParam.SourceVersion = DataRowVersion.Original
objDataAdapter = New OleDbDataAdapter(sQuery, objConn)
objDataAdapter.InsertCommand = objInsertCmd
objDataAdapter.DeleteCommand = objDeleteCmd
objDataAdapter.UpdateCommand = objUpdateCmd
objDataAdapter.Update(objDataSet, "articoli")
Catch e As Exception
System.Console.WriteLine(e.Message)
End Try
Close()
End Sub
Stampare il contenuto di una tablella del DataSet e' solo una questione
di esplorarla riga per riga. Nell'insieme Tables troviamo tutte
le tabelle presenti attualmente nel DataSet. I suoi elementi sono oggetti
DataTable che a loro volta contengono la Collection Rows
di oggetti DataRow,
cioe' record. Con il ciclo For Each scandiamo tutte le righe.
Ciascuna riga e' a sua volta un insieme di campi, che hanno appunto i
valori che vogliamo visualizzare. Accediamo ad essi tramite un indice,
es. objRow(0), objRow(1), objRow(2).
Public Sub ListaArticoli()
If objDataSet Is Nothing Then Exit Sub
Try
Dim table As DataTable = objDataSet.Tables("articoli")
Dim objRow As DataRow
System.Console.WriteLine()
For Each objRow In table.Rows
System.Console.WriteLine(" {0, 3} {1, -10} {2, 4}", _
objRow(0), objRow(1), objRow(2))
Next
Catch e As Exception
System.Console.WriteLine(e.Message)
End Try
End Sub
Quando vogliamo aggiungere una nuova riga alla tabella, usiamo il metodo
NewRow dell'oggetto DataTable. Questo ci restituisce un record che
possiamo riempire con i valori da inserire. Successivamente, aggiungiamo
il record alla tabella con il metodo Add della collection Rows.
Public Sub Inserimento(ByVal art As String, ByVal qty As String)
If objDataSet Is Nothing Then Exit Sub
Try
Dim table As DataTable = objDataSet.Tables("articoli")
Dim objRow As DataRow = table.NewRow()
objRow("articoli") = art
objRow("quantita") = qty
table.Rows.Add(objRow)
Catch e As Exception
System.Console.WriteLine(e.Message)
End Try
End Sub
Per eliminare un record, lo individuiamo tramite la sua chiave primaria,
cio' e' possibile grazie al metodo Find della collectionRows.
La riga si elimina con Delete
Public Sub Eliminazione(ByVal id As Int32)
If objDataSet Is Nothing Then Exit Sub
Try
Dim table As DataTable = objDataSet.Tables("articoli")
Dim objRow As DataRow = table.Rows.Find(id)
objRow.Delete()
Catch e As Exception
System.Console.WriteLine(e.Message)
End Try
End Sub
Anche per modificare un record e' necessario induviduarlo con Find.
Dopodiche', poiche' l'oggetto DataRow contiene un Hashtable, individuiamo il
campo da modificare con la sua chiave che corrisponde appunto al nome
del campo.
Public Sub Modifica(ByVal id As Int32, ByVal qty As String)
If objDataSet Is Nothing Then Exit Sub
Try
Dim table As DataTable = objDataSet.Tables("articoli")
Dim objRow As DataRow = table.Rows.Find(id)
objRow("quantita") = qty
Catch e As Exception
System.Console.WriteLine(e.Message)
End Try
End Sub
End Class
End Module
Ultimo aggiornamento 01/02/2004
|