Nella lezione precedente ci siamo occupati di collegare il nostro progetto con un database SQL Server. Ora ci concentreremo sull'interazione tra le WinForms e i comandi essenziali per l'interrogazione di una tabella del database. L'estrazione efficiente dei dati costituisce un aspetto cruciale per la funzionalità di qualsiasi applicazione. In VB.Net tale processo è mediato dalla definizione e dall'uso di comandi SQL appropriati.
Il .XSD Object (XML Schema Definition)
Precedentemente abbiamo aggiunto la nostra sorgente dati mediante l'interfaccia di Visual Studio. Quando si lavora con sorgenti dati in Visual Studio è possibile creare un DataSet
visivo utilizzando l'interfaccia grafica fornita dall'editor. Come già detto, avremmo potuto accedere al nostro database mediante codice ma abbiamo preferito questa modalità per sfruttare al meglio le funzionalità dell'IDE.
Così facendo, alla destra dell'interfaccia di Visual Studio, aprendo il tab "Esplora Soluzioni", qualora non fosse visibile, troveremo un oggetto con estensione .xsd
. In Visual Studio, un file .xsd
rappresenta uno schema XML (XML Schema Definition). Questo file viene utilizzato principalmente per definire la struttura di un set di dati XML. Nell'ambito della programmazione .NET, gli schemi XML vengono spesso utilizzati per definire la struttura di DataSet
. Un DataSet
è una rappresentazione in memoria di dati che possono provenire da varie fonti. Inclusi database, file XML e altro ancora.
Gli schemi XML (.xsd
) vengono utilizzati per definire la struttura del DataSet
. Comprese le tabelle, le colonne, le relazioni e altri dettagli. Quindi il file .xsd
è una rappresentazione visiva dello schema del DataSet
. Viene utilizzato per generare il codice necessario per interagire con i dati nel sorgente in un progetto .NET. Nella figura in basso viene mostrato l'oggetto con estensione .xsd
che rappresenta lo schema XML del nostro database.
Come accedere ad una tabella del database
Per poter accedere ad una tabella del database, copiamo e incolliamo il seguente codice su Visual Studio per poi analizzarlo:
Public Class Form1
' Dichiarazione del TableAdapter
Dim utentiTableAdapter As New provaDataSetTableAdapters.utentiTableAdapter()
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
' Dichiarazione del DataSet
Dim dataSet As New provaDataSet()
' Caricamento dei dati nel DataSet utilizzando il TableAdapter
utentiTableAdapter.Fill(dataSet.utenti)
' Visualizzazione dei dati
For Each utenteRow As provaDataSet.utentiRow In dataSet.utenti.Rows
Dim nome As String = utenteRow.nome
Dim cognome As String = utenteRow.cognome
MessageBox.Show($"Nome: {nome}, Cognome: {cognome}")
Next
End Sub
End Class
Il codice per l'accesso al database
Nel codice vediamo che viene creato un oggetto di tipo utentiTableAdapter
. La classe provaDataSetTableAdapters
è generata automaticamente da Visual Studio in base alle definizioni presenti nell'oggetto provaDataSet.xsd
. Nel file provaDataSet.xsd
troviamo le dichiarazioni delle classi TableAdapter
, tra cui utentiTableAdapter
. Queste classi si occupano di interagire con il database per eseguire operazioni di lettura, scrittura, aggiornamento ed eliminazione dei dati. La classe utentiTableAdapter
è generata in base alle impostazioni e alla configurazione definite durante la creazione dello schema DataSet
. Contiene tutti i metodi base per eseguire operazioni sulle righe della tabella "utenti".
Dopo aver istanziato un oggetto di tipo utentiTableAdapter
quello che facciamo è definire un gestore dell'evento Load
del form Form1
. In sostanza, il codice all'interno di Private Sub Form1_Load
verrà eseguito quando il form Form1
sarà caricato in memoria. A questo punto possiamo creare un oggetto di tipo provaDataSet
che è dichiarato come classe parziale che estende la classe di base DataSet
. Questo oggetto rappresenta un set di dati in memoria nel contesto di un'applicazione .NET ed è parte di ADO.NET. Un framework che offre librerie per l'accesso e la gestione dei dati.
Di cosa si occupa provaDataSet
Nello specifico provaDataSet
si occupa di:
- memorizzazione temporanea dei dati: è un contenitore in memoria che può mantenere una rappresentazione dei dati provenienti da una o più tabelle di un database. È utile per lavorare localmente con i dati senza la necessità di una connessione continua al database.
- Manipolazione dei dati: può aggiungere, modificare ed eliminare dati all'interno delle tabelle. Queste modifiche possono essere apportate localmente nel set di dati prima di essere propagate al database sottostante.
- Utilizzo con controlli di interfaccia utente: è utilizzato in combinazione con controlli di interfaccia utente come
DataGrid
oDataGridView
per visualizzare e modificare i dati nelle applicazioni Windows Forms. - Utilizzo con
TableAdapter
: la classeprovaDataSet
è spesso associata aTableAdapter
e rappresentano i canali di comunicazione tra il database e il set di dati. ITableAdapter
forniscono metodi per caricare, salvare e aggiornare i dati tra il database eprovaDataSet
.
Recupero dei dati
In utentiTableAdapter.Fill(dataSet.utenti)
: viene utilizzato il TableAdapter
di utentiTableAdapter
per riempire il DataSet
con i dati provenienti dalla tabella "utenti". Il metodo Fill
è responsabile di eseguire la query SQL per recuperare i dati e popolare la tabella utenti del DataSet
. For Each utenteRow As provaDataSet.utentiRow In dataSet.utenti.Rows
viene iterato attraverso le righe della tabella utenti all'interno del DataSet
. Con Dim nome As String = utenteRow.nome e Dim cognome As String = utenteRow.cognome
vengono estratti i valori delle colonne "nome" e "cognome" dalla riga corrente della tabella. Con MessageBox.Show($"Nome: {nome}, Cognome: {cognome}")
viene visualizzata una finestra di messaggio (MessageBox)
che mostra nome e cognome estratti dalla riga corrente della tabella.
Questa è una forma di output che mostra i dati recuperati dalla tabella. Il codice carica i dati di "utenti" nel DataSet
quando il form viene caricato. Quindi visualizza una finestra di messaggio contenente le informazioni sulla tabella, come nome e cognome, per ogni riga presente nel DataSet
. Come mostrato in figura.
Inserimento dati in una tabella
In questo paragrafo ci occuperemo di inserire dei dati (nome e cognome) nella tabella "utenti". Tramite l'uso di TextBox
che vengono generati via codice. Il codice riportato in basso può sicuramente essere migliorato, specie negli aspetti di gestione degli errori. Ma per adesso non è il nostro obiettivo principale. L'interfaccia contiene due TextBox
per l'inserimento del nome e del cognome, insieme a un pulsante "Inserisci Dati" che, quando premuto, chiama il metodo btnInserisciDati_Click
. Esso recupera i valori dalle TextBox
e chiama il metodo InserisciDatiUtenti
, passando il nome e il cognome come parametri. Il metodo InserisciDatiUtenti
tenta di inserire i dati nella tabella degli utenti utilizzando l'oggetto TableAdapter
, utentiTableAdapter
. L'ID nella tabella degli utenti è un campo auto-incrementante. Quindi viene passato Nothing
per tale campo durante l'inserimento.
Imports System.Data.SqlClient
Public Class Form1
' Oggetto TableAdapter generato automaticamente dal DataSet
Dim utentiTableAdapter As New provaDataSetTableAdapters.utentiTableAdapter()
Dim txtNome As New TextBox()
Dim txtCognome As New TextBox()
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
' Configurazione della TextBox per il nome
txtNome.Location = New Point(10, 10)
txtNome.Size = New Size(150, 20)
Me.Controls.Add(txtNome)
' Configurazione della TextBox per il cognome
txtCognome.Location = New Point(10, 40)
txtCognome.Size = New Size(150, 20)
Me.Controls.Add(txtCognome)
' Creazione di un pulsante per avviare l'inserimento
Dim btnInserisci As New Button()
btnInserisci.Text = "Inserisci Dati"
btnInserisci.Location = New Point(10, 70)
AddHandler btnInserisci.Click, AddressOf btnInserisciDati_Click
Me.Controls.Add(btnInserisci)
End Sub
Private Sub btnInserisciDati_Click(sender As Object, e As EventArgs)
' Recupera il testo dalle TextBox
Dim nome As String = txtNome.Text
Dim cognome As String = txtCognome.Text
' Chiamata al metodo per inserire i dati nella tabella
InserisciDatiUtenti(nome, cognome)
End Sub
Private Sub InserisciDatiUtenti(nome As String, cognome As String)
Try
' Inserisci dati nella tabella utilizzando il TableAdapter
utentiTableAdapter.Insert(nome, cognome) ' Passa Nothing per il campo id (auto-incremento)
' Messaggio di successo
MessageBox.Show("Dati inseriti con successo!")
Catch ex As SqlException
' Gestione specifica degli errori SQL
MessageBox.Show($"Errore SQL durante l'inserimento dei dati: {ex.Message}", "Errore SQL", MessageBoxButtons.OK, MessageBoxIcon.Error)
Catch ex As Exception
' Gestione generica degli errori
MessageBox.Show($"Errore durante l'inserimento dei dati: {ex.Message}", "Errore", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
End Class
Analizziamo il codice
Di seguito alcune informazioni generiche relative al codice precedente. Textbox
e Button
vengono creati dinamicamente durante il caricamento del modulo (Form) per consentire agli utenti di inserire dati. btnInserisciDati_Click
viene chiamato quando l'utente clicca su "Inserisci Dati". Recupera i dati dalle Textbox
e chiama il metodo InserisciDatiUtenti
per l'inserimento nel database.
InserisciDatiUtenti
gestisce l'inserimento dei dati nella tabella. Utilizza un Try...Catch
per gestire gli errori, con un blocco specifico per gli errori SQL e uno generico per altri tipi di errori. Le MessageBox
vengono utilizzate per fornire feedback sul risultato dell'operazione. Indicando se i dati sono stati inseriti correttamente o se si è verificato un errore.
Conclusioni
In questa lezione abbiamo fornito alcuni spunti per la gestione dei dati. Chiaramente gli aspetti da trattare sono molteplici ma quello che abbiamo appena introdotto è sufficiente per iniziare a sviluppare qualche semplice applicativo. Nella lezione successiva vedremo come gestire i file e le risorse in VB.NET.