ADO .NET Primer
Andrea Saltarello
Software Architect – Managed Designs S.r.l.
http://blogs.ugidotnet.org/pape
Sponsor
Struttura di ADO .NET
ADO .NET è composto da:
– Namespace System.Data: racchiude le primitive
indipendenti dalla tipologia di base dati.
• Sono tutte disconnesse
– .NET Managed Provider: implementano le primitive
necessarie all’accesso a specifiche basi dati
• System.Data.SqlClient per l’accesso a SQL Server 7+
• System.Data.OleDb per connettersi usando un OleDb
Provider
• System.Data.OracleClient
• System.Data.Odbc
.NET Data Providers
Implementano un insieme comune di
interfacce esponendo le classi:
– Connection: permette la connessione ad una
base dati
– Command: permette l’esecuzione di comandi
SQL e Stored Procedure
– DataReader: implementa un cursore forwardonly, read-only, client side
– DataAdapter: permette di “riempire” un
contenitore disconnesso
Classe Connection
Simile ad ADO old-style
La Connection String:
– Può essere specificata mediante un costruttore
parametrico
– Utilizza le stesse keyword di ADODB
– Richiede attenzione nella specifica del Provider:
• SqlClient non lo accetta
• System.Data.OleDb non supporta ODBC
Dim conSQL As New SqlConnection( )
conSQL.ConnectionString = "Integrated Security=True;" & _
"Data Source=LocalHost;Initial Catalog=Pubs;"
conSQL.Open( )
Classe Command
Possiamo creare un comando:
– Mediante il costruttore
– Mediante metodo CreateCommand
Possiamo eseguire un comando mediante i metodi:
– ExecuteReader: restituisce il DataReader in base ad una
query
– ExecuteScalar: è il metodo preferibile se il risultato è un
singleton
– ExecuteNonQuery: esegue un comando di azione
Dim commSQL As New SqlCommand( )
commSQL.Connection = conSQL
commSQL.CommandText = "Select Count(*) from Authors"
MessageBox.Show(commSQL.ExecuteScalar( ).ToString)
Invocare Stored Procedure
1. Creare un oggetto Command
2. Impostare CommandType al valore
StoredProcedure
3. Impostare la proprietà CommandText
4. Usare il metodo Add per creare e aggiungere
parametri
5. Impostare la proprietà ParameterDirection
6. Invocare ExecuteReader
7. Consumare i record, e chiudere il DataReader
8. Leggere i parametri di output e il valore di
ritorno
Invocare Stored Procedure: un
esempio
Usare un DataReader
Per usare un DataReader, possiamo:
– Avanzare alla posizione successiva mediante il
metodo Read(), che ritorna True finchè non si sono
consumati tutti i dati
– Leggere i valori dei campi mediante la proprietà Item,
oppure mediante i metodi GetXYZ()
Un DataReader impegna la propria connessione,
quindi:
– Non è possibile utilizzarla per eseguire comandi
– Dobbiamo ricordarci di chiuderlo mediante il metodo
Close()
Usare un DataReader: un
esempio
Dim commSQL As New SqlClient.SqlCommand( )
commSQL.Connection = conSQL
commSQL.CommandText ="Select au_lname,au_fname from authors"
Dim datRead As SqlClient.SqlDataReader
datRead = commSQL.ExecuteReader( )
Do Until datRead.Read = False
MessageBox.Show(datRead.GetString(1) & " " _
& datRead.GetString(0))
Loop
datRead.Close( )
DataReader
La classe DataSet
• E’ un contenitore disconnesso
• E’ assimilabile ad un “vettore di matrici”
• Permette di specificare vincoli e relazioni
tra i dati contenuti
• E’ accessibile in scrittura
• Permette di propagare le modifiche su un
DB
• Supporta nativamente la
(de)serializzazione in formato XML
La classe DataSet
DataSet
Tables
Relations
Oggetto
Table
Collezione
Columns
Column
Constraints
Constraint
Rows
Row
Relation
Popolare un DataSet
• Popolare un DataSet accedendo ad un RDBMS
Dim adaptSQL As New SqlClient.SqlDataAdapter( _
"Select * from authors", conSQL)
Dim datPubs As DataSet = New DataSet( )
adaptSQL.Fill(datPubs, "NewTable")
• Creare un DataSet in via programmatica
Dim datPubs As New DataSet( )
Dim tblAuthors As DataTable = New DataTable("authors")
tblAuthors.Columns.Add("AuthorID", System.Type.GetType _
("System.Int32"))
La classe DataAdapter
• E’ il collegamento tra il “mondo” connesso e
quello disconnesso
• Può “riempire” un dataSet avvalendosi di una
connessione chiusa
Dim adaptSQL As New SqlClient.SqlDataAdapter( _
"Select * from authors", conSQL)
Dim datPubs As New DataSet( )
adaptSQL.Fill(datPubs, "miaTabella")
' Accesso ai dati
adaptSQL.Update (datPubs, "miaTabella")
DataSet multi Tabella
• Creare la prima tabella
Dim mySqlDataAdapter As New SqlDataAdapter( 
"select * from customers", mySqlConnection)
Dim myDataSet As New DataSet()
mySqlDataAdapter.Fill(myDataSet, "Customers")
• Creare le tabelle successive
mySqlDataAdapter.SelectCommand.CommandText = 
"select * from orders"
mySqlDataAdapter.Fill(myDataSet,"Orders")
Customers
DataSet:
Orders
Data Tables
La classe DataTable
Ogni elemento della proprietà Tables è una
istanza della classe DataTable
La classe DataTable espone le proprietà:
– Columns: è una collezione di istanze di
DataColumn
– Rows: è una collezione di istanze della classe
DataRow
– Una istanza della classe DataRow:
• Mette a disposizione il contenuto delle proprie
colonne mediante la proprietà Item
Usare una DataTable: un
esempio
Dim numeroRighe As Int32 = unaTabella.Rows.Count
Dim indiceRiga As Int32
Dim unaRiga As DataRow
For indiceRiga = 0 To numeroRighe - 1
unaRiga = unaTabella.Rows(indiceRiga)
Dim nomeAutore As String = _
unaRiga.Item("au_fname").ToString()
Next
DataSet
DataSet: le Relazioni
• La classe DataSet espone la proprietà
Relations, che è una collezione di istanze
della classe DataRelation
• Un oggetto DataRelation:
– Definisce una associazione tra le colonne di
differenti DataTable
– definisce una associazione orientata alla
navigazione sui dati
– NON costituisce una constraint
Usare le Relazioni con i
DataSet
• Creare relazioni
Dim relPubsTitle As New DataRelation("PubsTitles", _
datPubs.Tables("Publishers").Columns("pub_id"), _
datPubs.Tables("Titles").Columns("pub_id"))
datPubs.Relations.Add(relPubsTitle)
• Accedere ai dati associati
Dim PubRow, TitleRow As DataRow, TitleRows( ) As DataRow
PubRow = datPubs.Tables("Publishers").Rows(0)
TitleRows = PubRow.GetChildRows("PubsTitles")
Usare Constraint
Il supporto alle constraint della classe DataSet
permette di:
– Creare constraint
• Classe ForeignKeyConstraints
• Classe UniqueConstraints
– Usare le constraint esistenti nel DB
adaptSQL = New SqlClient.SqlDataAdapter("Select title_id" _
& ", title, type, price from titles", conSQL)
adaptSQL.FillSchema(datPubs, schematype.Source, "Titles")
adaptSQL.Fill(datPubs, "Titles")
'Operazioni sui dati
adaptSQL.Fill(datPubs, "Titles")
Integrità Referenziale
Una constraint ForeignKeyConstraint:
– permette l’integrità referenziale
• Se la proprietà EnforceConstraints del DataSet è impostata
a True
– Determina le azioni effettuate nelle tabelle correlate
• Proprietà DeleteRule e UpdateRule
Azione
Descrizione
Cascade
Cancella o aggiorna le righe correlate. E’ il default.
SetNull
Imposta a DBNull il valore delle righe correlate.
SetDefault
Imposta al DefaultValue il valore delle righe correlate.
None
Nessuna azione/modifica, viene sollevata una eccezione.
DataRelation
Modificare i Dati
• Aggiungere righe
Dim drNewRow As DataRow = datPubs.Tables("Titles").NewRow
'Populate columns
datPubs.Tables("Titles").Rows.Add(drNewRow)
• Modificare righe
drChangeRow.BeginEdit( )
drChangeRow("Title") = drChangeRow("Title").ToString & " 1"
drChangeRow.EndEdit( )
• Cancellare righe
datPubs.Tables("Titles").Rows.Remove(drDelRow)
Aggiornare il database
• Possiamo ripercuotere le modifiche effettuate al DataSet
sul DB:
– Esplicitando il comando di aggiornamento
Dim comm As New SqlClient.SqlCommand("Insert titles" & _
"(title_id, title, type) values(@t_id,@title,@type)")
comm.Parameters.Add("@t_id",SqlDbType.VarChar,6,"title_id")
comm.Parameters.Add("@title",SqlDbType.VarChar,80,"title")
comm.Parameters.Add("@type",SqlDbType.Char,12,"type")
adaptSQL.InsertCommand = comm
adaptSQL.Update(datPubs, "titles")
• Generando automaticamente il comando di update
Dim sqlCommBuild As New SqlCommandBuilder(adaptSQL)
MsgBox(sqlCommBuild.GetInsertCommand.CommandText)
adaptSQL.Update(datPubs, "titles")
Links
http://www.ugidotnet.org
http://forum.ugidotnet.org
http://mobile.ugidotnet.org
Scarica

ADO .NET Primer