Prima di tutto, per chi volesse approfondire l'argomento, rimando ai numerosi post fatti da
Igor nonchè ovviamente ad
msdn, in particolare consiglio questo
articolo sulle
notifiche di query di
Bob Beauchemin per ADO.Net 2.0.
Ora torniamo, visto che le domande su ADO.Net rappresentano una buona parte dell'esame 70-316 ed è importante nella vita professionale di un programmatore, ai fondamentali....
Come lavora ADO.Net
Quando di lavora con gli archivi i tools messi a disposizione da ADO.Net ci vengono in aiuto, meno male!!!! La modalità di connessione ai dati utilizzata da ADO.Net è di default disconnessa, essa presenta diversi vantaggi:
- risparmio in termini di risorse di sistema
- maggior scalarità
- risparmio sulle licenze client necessarie
Questo perché il collegamento avviene giusto per il tempo necessario allo scambio dei dati tra il database e l'applicazione.
ADO.Net è formato da due componenti:
- DataSet che archivia i dati sulla macchina locale
- Data Provider che permette l'iterazione tra il programma ed il database
DataSet
La fonte dei dati può essere SQL Server Database, Access, XML, Oracle poiché come abbiamo detto ADO.Net lavora in modalità disconnessa di default occore avere una rappresentazione in-memory dei dati, a questo provvede il DataSet. Ma da cosa è composto un DataSet?
In pratica è composto da:
- oggetti tabelle dette DataTable ognuna delle quali rappresenta una singola tabella del nostro database origine
- la collection DataRelations dove ci aspettiamo di trovare le relazione tra le diverse tabelle
Vediamo un pò più in dettaglio come stanno le cose per le DataTable, esse sono rappresentate da due collection che unite formano lo schema della tabella:
- DataColumns ossia i campi
- Constraint (ne parleremo domani)
Se volessimo personalizzare un DataSet abbiamo a disposizione la collection ExtendedProperties (che ancora devo provare ).
Inoltre la DataTable contiene la DataRows collection, in pratica i record.
DataProvider
Il supporto allo scambio di dati tra il database ed il nostro programma è il compito del DataProvider che è formato a sua volte da più componenti(oggetti), che in ordine d'intervento sono:
- Connection come ci aspettiamo esso effettua la connessione con il database la proprietà che crea il canale di connessione con il database essa è la ConnectionString
- Command effettua una serie di comandi sui dati tramite SqlCommand e OleDbCommand quali (il significato sarà chiaro leggendo il resto del post):
- ExecuteNonQuery ad esempio esegue Insert,Delete o Update essi hanno in comune il fatto di non ritornare record
- ExecuteScalar ritornano un singolo valore dalla query effettuata su un database
- ExecuteReader ritornano un set di risultati da un DataReader
- DataReader provvede a restituire un recordset forward-only e read-only
- DataAdapter popola(fill) le tabelle del DataSet
C'è una domanda alla quale a questo punto è obbligo rispondere, quali sono i tipi di DataProvider che il .Net Framework ci mette a disposizione?
- SQL Server .Net per lavorare con le versioni SQL Server 7 o successive..............il nome della classe è SqlConnection
- OleDb .Net per lavorare con diversi tipi di database.........................................il nome della classe è OleDbConnection
- ODBC......................................................................................................il nome della classe è ODBCConnection
- Oracle.....................................................................................................il nome della classe è OracleConnection
Diamo per scontato che tutti conosciamo le basi di SQL (Structured Query Language), comunque per comodità ho riepilogato le fondamentali nel box sottostante:
/*
La struttura tipo è questa
*/
select campi from tabella
where la/le condizione/i con uso di AND, OR,NOT,BETWEEN LIKE,IN
ORDER BY campo rispetto al quale effettuiamo ordinamento DESC oppure ASC;
*/
Ricordo che con _ si sostituisce 1 carattere con il % più caratteri
(io li chiamo jolly ma se non ricordo male si dovrebbero chiamare wildcard)
/*
Facciamo un esempio:
-abbiamo una tabella Clienti
-ha diversi campi(in totale 10) tra i quali: IDCli,RagSoc,PIVA,Cell,Comune,Privacy
Il nostro problema è:
"Estrarre tutti i campi sopra detti dei clienti residenti
nel comune di Roma e Napoli, ordinandoli rispetto alla ragione sociale in ordine decrescente.
*/
select IDCli,RagSoc,PIVA,CEll,Comune,Privacy from Clienti
where Comune IN ('Roma','Napoli')
ORDER BY RagSoc DESC;
*/
Se invece avessimo voluto estratte tutti i campi avremmo fatto la seguente modifica
*/
select * from Clienti......
*/
/*
Vediamo adesso:
- UPDATE(modificare)
- DELETE(cancellare)
- INSERT INTO(inserire un nuovo record)
*/
/*NOTA:
Sia l'UPDATE che il DELETE non permettono il rolled back
ossia una volta fatto non si può tornare indietro.
*/
DELETE
/*
Come struttura è simile all'istruzione SELECT
SOLO che NON possiamo scegliere direttamente i campi
ma occorre utilizzare la clausola where
*/
DELETE FROM tabella WHERE condizione
/*
supponiamo di voler eliminare
il cliente con ragione sociale Bianchi
*/
DELETE FROM Clienti WHERE RagSoc='Bianchi';
/*
Vediamo ora l'UPDATE
*/
UPDATE nometabella
SET colonna1=valore1,......colonnaN = valoreN
[WHERE.[se vogliamo specificare quali aggiornare]..]
/*
Ad esempio supponiamo di volere modificare la ragione sociale del cliente
Rossi in Rossi Snc...procediamo come segue
*/
Update Clienti SET RagSoc='Rossi Snc' WHERE RagSoc='Rossi';
/*
*/
INSERT INTO
/*
La struttura generale è questa
*/
INSERT INTO tabella [(colonna1,....,colonnaN)]
VALUES (valore1,....,valoreN)];
/*
Ad esempio supponiamo di voler inserire un nuovo record ma di non disporre
di tutte le informazioni, questo non è un problema perchè le colonne
non specificate sono settate a null, dunque procediamo come segue
*/
INSERT INTO Clienti (RagSoc,PIVA,Comune)
VALUES ('Verdi Srl','0199937320','Venezia');
Panoramica passo passo i vari componenti e come funzionano
Facciamo una rapida panoramica, approfondiremo il discorso domani.
1° Problema: Stabilire la connessione tra il programma ed il database
Soluzione:
Veloce:
usiamo gli stumenti visuali di VS.Net quindi da menù View apriamo la Server Explorer e facendo click di destro su DataConnections scegliamo Add Connection che ci permette grazie alla dialog box Data Link poi seguiamo la procedura guidata
DA PROGRAMMATORE ( ice in erba ):
/*
dichiarimo ed istanziamo l'oggetto di nome laConn
*/
OleDbConnection laConn = new OleDbConnection();
/*
utilizziamo la ConnectionString per specificare il database da utilizzare è
ClientiItalia.mdb quindi creato con Access, nota che Microsoft.Jet.OLEDB.4.0 è per Access)
*/
laConn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0"+"DataSource=C:\\ClientiItalia.mdb";
2° Problema: Interagire con il database
Qui cosa usare dipende da che cosa dobbiamo fare:
- DataCommand per:
- aggiornare (Update,Cancel,INSERT)
- eseguire comandi che ritornino un singolo valore grazie ad ExecuteScalar
- eseguire un comando DDL (Database Definition Language) come CREATE TABLE o ALTER
- ottenere un result set read-only da un DataReader
- ottenere un result set da un XML stream (solo per la classe SqlCommand)
- ottener un result set da più tabelle
- lavorare con un DataAdapter
Vantaggio del DataCommand: metodo veloce ed efficiente per interagire con il database
Perchè richiede solo che la connessione sia attiva e non necessita l'interazione con il DataAdapter.
- DataReader per:
- disporre dei dati in modalità read-only o forward-only
- DataAdapeter per
- in sintesi per tutto quello non specificato sopra
Vediamo velocemente come utilizzare il DataReader (maggiori dettagli domani)
/*
supponiamo d'avere due oggetti
- un OleDbCommand di nome mioOleDbC
- un SqlCommand denominato mioSqlC
*/
System.Data.OleDb.OleDbDataReader mioOleDbC;
System.Data.SqlClient.SqlDataReader mioSqlC;
/*
creiamo OleDbReader ed assegniamolo alla variabile
*/
mioOleDbReader = mioOleDbC.ExecuteReader();
// facciamo la stessa cosa nel caso Sql
mioSqlReader=mioSqlC.ExecuteReader();
/*
Ora leggiamo i record, ricordando che il DataReader si posiziona
prima del primo recordo del set ed il metodo Read legge il record se
il record è disponibile ritorna il valore true ed il DataReader
avanza al record successivo, altrimenti abbiamo false.
Per l'operazione conviene utilizzare il while
*/
while (mioDataReader.Read());
{
object Oggetto=mioDataReader[5];
object altroOggetto=mioDataReader["Comune"];
}
/*
dopo aver letto i dati occorre chiudere la connessione,
altrimenti, il nostro DataReader mantiene l'accesso esclusivo ad essa e non può
essere utilizzata da nessun altro oggetto.
*/
mioDataReader.Close();
/*
Ora supponiamo di dover riaprire la connessione e di dover accedere a delle colonne del DataReader
*/
laConn.Open();
//
//....codice omesso
//
//chiudiamo il DataReader
mioDataReader.Close();
//
//visto che abbiamo finito chiudiamo anche la connessione
//
laConn.Close();
Ed ora vado a fare "qualche" test, sono in arretrato pazzesco ....ma la notte per fortuna è lunga.
powered by IMHO 1.3