C# - Lavorare con database MySql
C#
Note sulle installazioni
- Per connettersi a un Database MySql occorre innanzi tutto installarlo. Per questa operazione fare riferimento al sito del produttore (Oracle).
- Installare anche MySql Workbench che è un ambiente di gestione del database completo.
- È necessario installare anche il connettore per .NET, che si trova sempre nel sito del produttore. Questo è il componente che permette la connessione al database tramite C#. La versione nel momento in cui scrivo, è la 6.9.9.
Riferimenti al progetto Visual Studio
- Nel progetto C# che si vuole realizzare, bisogna aggiungere un riferimento alla dll fornita dal produttore di MySql.
- L'operazione è questa: in 'Esplora Soluzioni -> Riferimenti', click destro e selezionare 'Aggiungi Riferimento...'.
- Si apre la form 'Gestione riferimenti' dalla quale si sceglie il riferimento da aggiungere. Cercare 'MySql.Data' che dovrebbe trovarsi in 'Assembly -> Estensioni'. Qualora ci fossero più righe, il Tooltip che appare sull'estensione, ne indica il percorso. È facile capire che i vari percorsi fanno riferimento alla diverse versioni del Framework installate. Selezionare il file voluto (compare un piccolo checkbox sulla sinistra) e cliccare su 'OK'.
- Per la gestione della connessione è comodo avere una semplice classe di interfaccia.
- Per aggiungere una classe, in 'Esplora Soluzioni', click destro sul progetto che fa parte della soluzione. Selezionare 'Aggiungi -> Classe' e dare un nome alla nuova classe, per esempio 'GestioneMySql.cls'.
- Modificare la classe in 'public' e 'static' e aggiungere il seguente codice.
{
public static string StringaConnessione =
"Data Source=localhost;Database=test;userid=xxx;password=yyy;";
public static MySqlConnection Connessione = new MySqlConnection(StringaConnessione);
public static bool ApriConnessione()
{
try
{
if (Connessione.State != ConnectionState.Open)
{
Connessione.ConnectionString = GestioneMySql.StringaConnessione;
Connessione.Open();
}
return true;
}
catch (Exception ex)
{
return false;
}
}
public static bool ChiudiConnessione()
{
try
{
if (Connessione.State != System.Data.ConnectionState.Closed)
{
Connessione.Close();
}
return true;
}
catch
{
return false;
}
}
// Le transazioni solo con database di tipo INNODB
private static MySqlTransaction Transazione = null;
public static void TransazioneBegin()
{
Transazione = Connessione.BeginTransaction();
}
public static void TransazioneCommit()
{
Transazione.Commit();
}
public static void TransazioneRollback()
{
Transazione.Rollback();
}
}
Transazione.Rollback();
}
}
- Nel codice precedente, modificare la stringa di connessione, chiamata appunto 'StringaConnessione', in base al proprio database. In particolare, 'Data Source' è l'indirizzo IP della macchina che contiene il database, oppure 'localhost' se il database è sulla macchina locale. 'Database' è lo schema (cioè un insieme di tabelle) di default dove avverrà la connessione. 'userid' è l'utente che ha i permessi di lettura ed eventualmente di scrittura sulle tabelle. 'password' è la password dell'utente.
- Questa classe ha soltanto un oggetto pubblico di tipo 'MySqlConnection', due metodi per l'apertura e per la chiusura della connessione, un oggetto privato e tre metodi pubblici per la gestione delle transazioni.
- La classe fa riferimento ad oggetti presenti nei 'Namespace' seguenti, che devono essere aggiunti in testa al file:
using System.Data;
using MySql.Data.MySqlClient;
Tabella di esempio
- Si supponga che nel database sia presente la schema "test" contenente la tabella "persone".
- Questa tabella ha i seguenti campi:
- Nome, VARCHAR(50)
- DataNascita, DATETIME
- Stipendio, INT
- Si aggiunga anche qualche record, per esempio:
Query di selezione (in un DataReader)
- Il codice seguente, esegue una semplice query di selezione (il codice può essere copiato per esempio nell'evento di un bottone).
- Il ciclo 'while' rende disponibili nel DataReader 'dr', tutti i campi selezionati nella query.
try
{
// Apertura connessione
if (!GestioneMySql.ApriConnessione())
throw new Exception("Errore nell'apertura della connessione.");
// Query da eseguire
StringBuilder sb = new StringBuilder();
sb.AppendLine(" SELECT IdPersona, Cognome, Nome, DataNascita, Stipendio ");
sb.AppendLine(" FROM test.persone ");
using (MySqlCommand cmd = new MySqlCommand(sb.ToString(), GestioneMySql.Connessione))
{
using (MySqlDataReader dr = cmd.ExecuteReader())
{
while (dr.Read())
{
int idPersona = dr.GetInt32("IdPersona");
string cognome = dr.GetString("Cognome");
string nome = dr.GetString("Nome");
DateTime dataNascita = dr.GetDateTime("DataNascita");
int stipendio = dr.GetInt32("Stipendio");
}
}
}
// Chiusura connessione
if (!GestioneMySql.ChiudiConnessione())
throw new Exception("Errore nella chiusura della connessione.");
}
catch (Exception ex)
{
GestioneMySql.ChiudiConnessione();
MessageBox.Show("Errore: " + ex.Message);
}
Dal DataReader al DataTable
- Se, oltre al DataReader, serve anche un DataTable con i risultati della query, basta semplicemente aggiungere le seguenti righe subito dopo il ciclo 'while', ma all'interno dello 'using' che definisce il DataReader.
dt.Load(dr);
- Se invece serve solo il DataTable (senza il DataReader), utilizzare il codice nel paragrafo successivo.
Query di selezione (in un DataTable)
- Se serve un DataTable con i risultati della query, utilizzare il codice seguente.
{
// Apertura connessione
if (!GestioneMySql.ApriConnessione())
throw new Exception("Errore nell'apertura della connessione.");
DataTable dt = new DataTable();
// Query da eseguire
StringBuilder sb = new StringBuilder();
sb.AppendLine(" SELECT IdPersona, Cognome, Nome, DataNascita, Stipendio ");
sb.AppendLine(" FROM test.persone ");
using (MySqlCommand cmd = new MySqlCommand(sb.ToString(), GestioneMySql.Connessione))
{
using (MySqlDataAdapter da = new MySqlDataAdapter(cmd))
{
da.Fill(dt);
}
}
// Chiusura connessione
if (!GestioneMySql.ChiudiConnessione())
throw new Exception("Errore nella chiusura della connessione.");
}
catch (Exception ex)
{
GestioneMySql.ChiudiConnessione();
MessageBox.Show("Errore: " + ex.Message);
}
- Quando i dati sono in un DataTable è molto facile caricare una DataGridView, come descritto nel paragrafo successivo.
Caricare una DataGridView
- Quando si hanno i dati in un DataTable, per caricarli in una DataGridView è sufficiente aggiungere le seguenti poche righe di codice dopo l'istruzione 'da.Fill(dt);'.
dgv.AutoGenerateColumns = true;
dgv.DataSource = dt;
dgv.Refresh();
- L'oggetto 'dgv' è appunto la DataGridView aggiunta alla form.
Query di selezione scalare
- Una query di esecuzione scalare è una query che estrae il primo campo dal primo record.
- È particolarmente efficiente.
- Ecco un esempio.
{
// Apertura connessione
if (!GestioneMySql.ApriConnessione())
throw new Exception("Errore nell'apertura della connessione.");
// Query da eseguire
StringBuilder sb = new StringBuilder();
sb.AppendLine(" SELECT MAX(IdPersona) ");
sb.AppendLine(" FROM test.persone ");
using (MySqlCommand cmd = new MySqlCommand(sb.ToString(), GestioneMySql.Connessione))
{
int maxId = (int)cmd.ExecuteScalar();
}
// Chiusura connessione
if (!GestioneMySql.ChiudiConnessione())
throw new Exception("Errore nella chiusura della connessione.");
}
catch (Exception ex)
{
GestioneMySql.ChiudiConnessione();
MessageBox.Show("Errore: " + ex.Message);
}
- Una osservazione riguardo l'esempio precedente. La funzione Max() di MySql restituisce un valore a 32 bit perciò è richiesto un cast verso una variabile 'int'. Se si dovesse utilizzare una query scalare con la funzione Count() di MySql (che restituisce un valore a 64 bit) il cast va fatto verso una variabile 'long'.
Query di aggiornamento
- Ecco un esempio di una query di aggiornamento, quindi di una "UPDATE" o di una "DELETE".
- Questo tipo di query restituisce il numero di record sui quali ha avuto effetto la query.
{
// Apertura connessione
if (!GestioneMySql.ApriConnessione())
throw new Exception("Errore nell'apertura della connessione.");
// Query da eseguire
StringBuilder sb = new StringBuilder();
sb.AppendLine(" UPDATE test.persone ");
sb.AppendLine(" SET Stipendio = Stipendio + 1 ");
sb.AppendLine(" WHERE IdPersona = 2 ");
using (MySqlCommand cmd = new MySqlCommand(sb.ToString(), GestioneMySql.Connessione))
{
int numRighe = cmd.ExecuteNonQuery();
}
// Chiusura connessione
if (!GestioneMySql.ChiudiConnessione())
throw new Exception("Errore nella chiusura della connessione.");
}
catch (Exception ex)
{
GestioneMySql.ChiudiConnessione();
MessageBox.Show("Errore: " + ex.Message);
}