Nonostante le tecnologie Microsoft dispongano di soluzioni proprie per la persistenza dei dati (si pensi a SQL Server, ma anche ad Access), l'integrazione dei linguaggi del framework .NET con MySQL non è rara.
A tale scopo esiste un pacchetto, un Connector, offerto da MySQL per l'integrazione con applicativi .NET. In questa lezione vedremo proprio come utilizzare il Connector/NET su C#.
Connector/NET: download ed installazione
Connector/NET può essere scaricato tramite l'apposita pagina/ del sito ufficiale di MySQL. È disponibile nelle versioni per Mono (piattaforma .NET utilizzabile su sistemi Unix-like), Windows o come codice sorgente e, per ognuno di questi casi, sono fornite le appropriate istruzioni di installazione.
Focalizzandoci sull'installazione per Windows, esistono due modi per utilizzare il driver. Al primo si è già accennato in una lezione di questa guida: l'installazione di MySQL su Windows porta con sé una serie di tool accessori, tra cui proprio i Connectors per la programmazione.
Altrimenti, lo si può comunque scaricare in modalità standalone, separatamente dal DBMS, come pacchetto in formato .msi.
L'esempio
Nel seguito vedremo come utilizzare le classi fornite con Connector/NET.
Il server MySQL utilizzato come controparte avrà i seguenti parametri di connessione:
Parametro | Valore |
---|---|
Indirizzo di rete | localhost |
Porta TCP | 3306 (il valore di default) |
Username | root |
Password | secret |
Database | Contatti |
Infine, la tabella che manipoleremo sarà così definita:
CREATE TABLE `persone` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`nome` varchar(50) NOT NULL,
`cognome` varchar(50) NOT NULL,
`eta` tinyint(3) unsigned NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
Il codice
Dopo l'installazione del Connector, dovremo renderlo disponibile nel nostro progetto. Supponendo di utilizzare Visual Studio, l'IDE fornito da Microsoft per il framework .NET, dovremo inserire un riferimento alle classi, come mostrato nella figura seguente:
L'esempio che segue apre una connessione dal programma C# al server MySQL e svolge un'operazione di inserimento tramite Prepared Statement, ed una query che legge e stampa in output il contenuto della tabella.
La connessione, stabilita tramite oggetto MySqlConnection
, è definita mediante una connection string i cui parametri hanno il seguente significato:
Parametro | Descrizione |
---|---|
Server | Indirizzo IP a cui risponde il server MySQL |
Uid | Username dell'account MySQL |
Password | Password dell'account MySQL |
Database | Nome del database a cui collegarsi |
MySqlConnection conn = new MySqlConnection("SERVER=localhost;database=Contatti;uid=root;password=secret"); MySqlCommand cmd = new MySqlCommand(); try { conn.Open(); String insert = "INSERT INTO persone (cognome,nome,eta) VALUES (@nome,@cognome,@eta)"; cmd.Connection = conn; cmd.CommandText = insert; cmd.Prepare(); cmd.Parameters.AddWithValue("@nome", "Nunzio"); cmd.Parameters.AddWithValue("@cognome", "Neri"); cmd.Parameters.AddWithValue("@eta", 28); cmd.ExecuteNonQuery(); String query = "SELECT * FROM persone"; MySqlCommand qrycmd = new MySqlCommand(query, conn); MySqlDataReader reader = qrycmd.ExecuteReader(); while (reader.Read()) { Console.WriteLine(reader["cognome"] + " " + reader["nome"]); } } catch (MySqlException e) { // gestione dell'eccezione } finally { if (conn!=null) conn.Close(); }
L'esecuzione dei comandi si snoda lungo le seguenti di fasi:
- connessione al database;
- definizione del comando da eseguire;
- eventuale lettura dei risultati dell'operazione svolta;
- chiusura della connessione.
La connessione deve essere aperta prima dell'utilizzo con il metodo Open
, e chiusa al termine delle operazioni con Close
. Una sua proprietà interna, State
, fornisce informazione sullo stato attuale della connessione.
Che si voglia eseguire una operazione di modifica o un'interrogazione, è comunque necessario istanziare un oggetto MySqlCommand
. Un oggetto di questo tipo, per agire, ha bisogno di almeno due elementi: un comando SQL (definito nella proprietà CommandText
) ed una connessione tramite la quale comunicare con il DBMS (definita nella proprietà Connection
).
Il comando relativo all'inserimento viene svolto come Prepared Statement, pertanto si assegnano le proprietà relative al comando SQL e alla connessione, e viene invocato il metodo Prepare
.
I parametri vengono definiti in SQL con un nome simbolico preceduto da @
: ad esempio, @nome
.
Al momento dell'esecuzione della query devono essere assegnati i parametri alla proprietà Parameters
tramite il metodo AddWithValue
.
Nel caso della query, invece, non si usa un Prepared Statement, perciò il comando SQL e la connessione vengono passati direttamente tramite costruttore.
Comunque venga definito un MySqlCommand
, affinchè svolga le operazioni per le quali è stato configurato se ne deve ordinare l'esecuzione. Questi i metodi che lo permettono:
-
ExecuteNonQuery
: utilizzato per i comandi di modifica, fornisce come risultato il numero di righe coinvolte. Nell'esempio lo usiamo per eseguire l'INSERT
; -
ExecuteReader
: usato per le query di selezione, restituisce un cursore forward-only e read-only; -
ExecuteScalar
: ritorna un solo valore presente alla prima colonna della prima riga, mentre tutti gli altri dati risultati vengono ignorati. Tipicamente è usato con operazioni tipoSELECT COUNT
e simili, che forniscono un solo valore.
Il risultato della query viene letto tramite un oggetto MySqlDataReader
, che rappresenta il cursore che legge i dati. Il suo utilizzo prevede lo scorrimento in avanti, una riga alla volta, ad ogni invocazione del metodo Read
. La riga raggiunta può essere letta semplicemente specificando il nome di un campo della tabella tra parentesi quadre.
Usare ADO.NET
Il codice visto nel paragrafo precedente ha il difetto di utilizzare classi espressamente orientate a MySql. Se si volesse utilizzare lo stesso stralcio di C# nell'interazione con un altro DBMS lo si dovrebbe modificare radicalmente. Una soluzione alternativa esiste, ed è basata su ADO.NET, il sottosistema di accesso ai dati offerto dal .NET Framework.
ADO.NET offre una serie di vantaggi tra cui l'uniformità nell'accesso ai dati in termini di classi utilizzate, tipi di dato, metodi di progettazione.
In pratica, permette di scrivere del codice generico, riutilizzabile con qualsiasi DBMS che offra un driver da integrare con ADO.NET. Il Connector/NET di MySQL nasce perfettamente compatibile con ADO.NET, il che permette di utilizzarlo come driver.
Per fare ciò è necessario sostituire tutti i riferimenti alle classi del Connector con le corrispondenti classi astratte di ADO.NET, e lo svolgimento del codice seguirà il medesimo percorso:
-
connessione: useremo
DbConnection
anzichéMySqlConnection
; -
esecuzione del comando: ci sarà
DbCommand
, non piùMySqlCommand
; -
lettura dei risultati: il cursore sarà gestito con
DbDataReader
al posto diMySqlDataReader
.
La connection string avrà lo stesso formato, ma la connessione sarà ottenuta in una maniera diversa:
DbProviderFactory factory = DbProviderFactories.GetFactory("MySql.Data.MySqlClient"); DbConnection conn = factory.CreateConnection();
DbProviderFactory
rappresenta un oggetto che permette la creazione di una connessione di un tipo specifico, indicato nel parametro di GetFactory
ma gestito tramite riferimenti a classi generiche. In un codice così impostato la stringa MySql.Data.MySqlClient
è l'unico elemento che svela l'uso di MySQL: la sua sostituzione permetterebbe il riutilizzo integrale del codice C# con un altro DBMS.
A titolo di esempio, quello che segue è il codice che permette lo svolgimento della query:
String query = "SELECT * FROM persone"; DbCommand qrycmd = conn.CreateCommand(); qrycmd.CommandText = query; qrycmd.Connection = conn; DbDataReader reader = qrycmd.ExecuteReader(); while (reader.Read()) { Console.WriteLine(reader["cognome"] + " " + reader["nome"]); }