adszone.org
venerdì 20 settembre 2024
"Il modo corretto di pensare il software"
home
consulenza  vb.net  contatti 
  Visual Basic .NET
  DataSet e DataAdapter
Domande

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