1 / 70 ADO.NET, i Data Provider e l'architettura connessa Silvano Coriani Developer & Platform...
-
Upload
ambrogino-rossi -
Category
Documents
-
view
215 -
download
1
Transcript of 1 / 70 ADO.NET, i Data Provider e l'architettura connessa Silvano Coriani Developer & Platform...
1 / 70
ADO.NET, i Data Provider e l'architettura connessa
Silvano CorianiDeveloper & Platform Evangelism
MCTrainerMCSDeveloperMCADeveloperMCSEInternetMCDBA
2 / 70
Da dove iniziare...
3 / 70
AgendaAgenda
4 / 70
.NET Data Access Overview.NET Data Access Overview
5 / 70
.NET Application.NET Application
ODBCODBC
OLE DBOLE DB
Other DBMSOther DBMSNon-relationalNon-relational
sourcessources
OLE DB ProviderOLE DB Provider
SQL ServerSQL Server
System.Data.SqlClientSystem.Data.SqlClient System.Data.OleDbSystem.Data.OleDbSystem.Data.OracleSystem.Data.Oracle
OracleOracle
DataSetDataSet
System.Data.OdbcSystem.Data.Odbc
6 / 70
.NET Data Provider
• System.Data
7 / 70
.NET Data Provider
• connessaCommand
8 / 70
.NET Data Provider
• DataAdapter• DataReader
9 / 70
ADO.NET e SQL Server 2000
10 / 70
SqlClient .NET Data Provider
11 / 70
SqlClient Managed Provider
• Non utilizza direttamente i cursori server di SQL Server– Nel caso, occorrono comandi T-SQL
espliciti (OPEN CURSOR, sp_cursor, sp_executesql ecc.)
– Oppure utilizzare ADO 2.x attraverso COM Interop
• Permette di interagire con le funzionalità XML di SQL Server 2000– ExecuteXmlReader()
12 / 70
SqlClient .NET Data Provider Object Model
SqlConnection
SqlCommand
SqlParameterCollectionSqlDataReader
SqlParameter
System.Xml.XmlReader
Object
13 / 70
SqlClient e il CLRSqlClient e il CLR
Common Language RuntimeCommon Language Runtime
SqlServerSqlServer
SqlClientSqlClient
TDSTDS
ParserParser
14 / 70
Accesso ai dati nel database Accesso ai dati nel database serverserver
15 / 70
Query ad-hocQuery ad-hoc
16 / 70
Prepare / ExecutePrepare / Execute
• PreparedSqlCommandPreparedSqlCommand
17 / 70
sp_executesqlsp_executesql
• Alternativa valida alle stored procedureAlternativa valida alle stored procedure– Elimina la gestione lato server Elimina la gestione lato server
• Se si vuole ottenere il riutilizzo del piano Se si vuole ottenere il riutilizzo del piano di esecuzione, anche qui occorre definire di esecuzione, anche qui occorre definire correttamente I parametri con il relativo correttamente I parametri con il relativo tipotipo
• Eseguita in modalità RPCEseguita in modalità RPC– Più efficiente nell’esecuzione sul serverPiù efficiente nell’esecuzione sul server– Riutilizzo del piano di esecuzione della queryRiutilizzo del piano di esecuzione della query
exec sp_executesql N‘Insert T1 Values (@p)’,N’@p float’,1exec sp_executesql N‘Insert T1 Values (@p)’,N’@p float’,1
18 / 70
Stored ProcedureStored Procedure
• WITH RECOMPILEWITH RECOMPILE
19 / 70
Stored ProcedureStored Procedure
• SqlCommandCommandTypeSqlCommandCommandType– Definizione di tutti i parametri tipizzati Definizione di tutti i parametri tipizzati
utilizzati dalla stored procedureutilizzati dalla stored procedure– MAIMAI
20 / 70
Classica Stored ProcedureClassica Stored Procedure
CREATE PROC spGetCustomerOrdersCREATE PROC spGetCustomerOrders
@CustomerID int@CustomerID int
@NumOrder int OUTPUT@NumOrder int OUTPUT
ASAS
-- Validazione di parametri di input-- Validazione di parametri di input
......
-- Logica applicativa (eventualmente chiama altre SP)-- Logica applicativa (eventualmente chiama altre SP)
......
-- Restituzione di uno o più result set-- Restituzione di uno o più result set
......
-- Restituisco il valore di ritorno-- Restituisco il valore di ritorno
21 / 70
Stored Procedure FOR XMLStored Procedure FOR XML
CREATE PROC spGetCustomerOrdersXMLCREATE PROC spGetCustomerOrdersXML@CustomerID int@CustomerID int@NumOrder int OUTPUT@NumOrder int OUTPUT
ASAS-- Validazione di parametri di input-- Validazione di parametri di input......-- Logica applicativa (eventualmente chiama altre SP)-- Logica applicativa (eventualmente chiama altre SP)......-- Restituzione di uno o più result set-- Restituzione di uno o più result setSELECTSELECT
C.CustomerID,O.OrderID,O.OrderDateC.CustomerID,O.OrderID,O.OrderDateFROMFROM
Customer C Left Join Orders O ON C.CustomerID=O.CustomerIDCustomer C Left Join Orders O ON C.CustomerID=O.CustomerIDWHEREWHERE
C.CustomerID = @CustomerIDC.CustomerID = @CustomerIDFOR XML AUTO, ELEMENTS FOR XML AUTO, ELEMENTS –- o EXPLICIT–- o EXPLICIT-- Restituisco il valore di ritorno-- Restituisco il valore di ritorno
22 / 70
Posso passare un set di record ad una Posso passare un set di record ad una SP?SP?
CREATE PROC spInsertCustomersXMLCREATE PROC spInsertCustomersXML@RecordSetXML varchar(1024)@RecordSetXML varchar(1024)
ASAS-- Carico il doc XML nel DOM-- Carico il doc XML nel DOMsp_xml_preparedocumentsp_xml_preparedocument @h OUTPUT, @ @h OUTPUT, @ RecordSetXML RecordSetXML -- Eseguo un inserimento in una tabella filtrando-- Eseguo un inserimento in una tabella filtrando-- le informazioni che mi servono attraverso XPath-- le informazioni che mi servono attraverso XPathOpenXMLOpenXML(@h,'//Customer')(@h,'//Customer')
WITH (CustomerID varchar(5) '@ID', WITH (CustomerID varchar(5) '@ID', CompanyName CompanyName
varchar(32),'@name')varchar(32),'@name')-- Rimuovo il documento dalla memoria-- Rimuovo il documento dalla memoriasp_xml_removedocumentsp_xml_removedocument
23 / 70
SQL Server 2000 Best SQL Server 2000 Best PracticesPractices
24 / 70
CursoriCursori
• row-basedrow-based– setset
25 / 70
SqlConnectionSqlConnection
• IDbConnectionIDbConnection• ConnectionStringSqlCommandSqlDataReaConnectionStringSqlCommandSqlDataRea
derder– Close()Dispose()Close()Dispose()
• BeginTransactionBeginTransaction– SqlTransactionSqlTransaction
26 / 70
SqlConnectionSqlConnection• AttachDBFilenameSqlClientPermissionAttachDBFilenameSqlClientPermission
27 / 70
SqlConnectionSqlConnection
• SqlCommandSqlDataAdapterSqlCommandSqlDataAdapter
[Visual Basic][Visual Basic]
Dim nwindConn As SqlConnection = New SqlConnection("Data _ Dim nwindConn As SqlConnection = New SqlConnection("Data _ Source=localhost;Integrated Security=SSPI;Initial Catalog=northwind")Source=localhost;Integrated Security=SSPI;Initial Catalog=northwind")
nwindConn.Open()nwindConn.Open()
[C#][C#]
SqlConnection nwindConn = new SqlConnection("Data Source=localhost; Integrated SqlConnection nwindConn = new SqlConnection("Data Source=localhost; Integrated Security=SSPI; Initial Catalog=northwind");Security=SSPI; Initial Catalog=northwind");
nwindConn.Open();nwindConn.Open();
28 / 70
SqlCommandSqlCommand
29 / 70
SqlCommandSqlCommand• Implementa l’interfaccia IDbCommandImplementa l’interfaccia IDbCommand
– ExecuteReader()ExecuteReader()• Da utilizzare quando è previsto un result set come Da utilizzare quando è previsto un result set come
ritornoritorno– ExecuteScalar()ExecuteScalar()
• Da utilizzare per aggregazioni o risultati di calcoliDa utilizzare per aggregazioni o risultati di calcoli• Ritorna solo la prima colonna della prima riga, gli Ritorna solo la prima colonna della prima riga, gli
altri dati vengono persialtri dati vengono persi– ExecuteNonQuery()ExecuteNonQuery()
• Ottimizzato per query che non ritornano result set Ottimizzato per query che non ritornano result set ma solo parametri di ritorno o numero di record ma solo parametri di ritorno o numero di record modificatimodificati
– ExecuteXmlReader()ExecuteXmlReader()
30 / 70
SqlCommand e query libereSqlCommand e query libereDim sqlConn As SQLConnection Dim sqlCmd As SQLCommand Dim rowsAffected As Integer Try
' Creo la connessione sqlConn = New SQLConnection(myConnString) ' Creo il comando sqlCmd = New SQLCommand() ' specifico il tipo di comando With sqlCmd
.CommandType = CommandType.Text
.CommandText = "Insert Customers (Alias, CustomerName) _ Values ('myAlias','myName')"
.Connection = sqlConn End With ' apro la connessione sqlConn.Open() ' eseguo il comando, vengono ritornate le righe inserite rowsAffected = sqlCmd.ExecuteNonQuery()
Catch e As Exception ' gestisco l’eccezione …
Finally ' chiudo la connesione sqlConn.Close()
End Try
31 / 70
SqlCommand e le Stored SqlCommand e le Stored ProcedureProcedure
• ParametersParameters
32 / 70
SqlCommand e le Stored SqlCommand e le Stored ProcedureProcedure
• ExecuteReader()DataReaderExecuteReader()DataReader• DBNull.ValueDBNull.Value per impostare a null per impostare a null
un parametro di input di una SPun parametro di input di una SP• CommandBehaviorCommandBehavior
33 / 70
SqlCommand e le Stored SqlCommand e le Stored ProcedureProcedure
sqlConn = New SQLConnection(myConnString)
' Create a new command object
sqlCmd = New SQLCommand()
' Specify the stored procedure and connection
With sqlCmd
.CommandType = CommandType.StoredProcedure
.CommandText = "InsertCustomer"
.Connection = sqlConn
End With
' Define and add a parameter to the parameters collection
param = sqlCmd.Parameters.Add(New SQLParameter("@p", SQLDBType.NVarChar, 100)
With param
.Direction = ParameterDirection.Input
' Set the parameter value
.Value = “xyz"
End With
' Add remaining parameters
…
' Open the connection
sqlConn.Open()
' Execute the command
rowsAffected = sqlCmd.ExecuteNonQuery()
34 / 70
SqlDataReaderSqlDataReader• SqlCommandSqlCommand• Read()IEnumerableRead()IEnumerable
35 / 70
SqlDataReaderSqlDataReader
• IDataReaderIDataRecordIDataReaderIDataRecord– Per accesso a informazioni in formato Per accesso a informazioni in formato
rettangolare e nonrettangolare e non
• È possibile accedere ai dati nelle È possibile accedere ai dati nelle singole colonne per indicenome del singole colonne per indicenome del campo o attraverso metodo campo o attraverso metodo accessori dedicati ai tipi di dato accessori dedicati ai tipi di dato contenuticontenuti– GetDateTime()GetDouble()GetGuid()GetDateTime()GetDouble()GetGuid(), ,
GetInt32()GetInt32()
36 / 70
SqlDataReaderSqlDataReader• NextResult()NextResult()• La struttura del result set è La struttura del result set è
descritta attraverso una “schema descritta attraverso una “schema table”table”– GetSchemaTable()GetSchemaTable()
37 / 70
Utilizzo di SqlDataReaderUtilizzo di SqlDataReader
[Visual Basic][Visual Basic]
Dim myReader As SqlDataReader = myCommand.ExecuteReader()Dim myReader As SqlDataReader = myCommand.ExecuteReader()
Do While myReader.Read()Do While myReader.Read()
Console.WriteLine(vbTab & "{0}" & vbTab & "{1}", myReader.GetInt32(0), Console.WriteLine(vbTab & "{0}" & vbTab & "{1}", myReader.GetInt32(0), myReader.GetString(1))myReader.GetString(1))
LoopLoop
myReader.Close()myReader.Close()
[C#][C#]
SqlDataReader myReader = myCommand.ExecuteReader();SqlDataReader myReader = myCommand.ExecuteReader();
while (myReader.Read())while (myReader.Read())
Console.WriteLine("\t{0}\t{1}", myReader.GetInt32(0), myReader.GetString(1));Console.WriteLine("\t{0}\t{1}", myReader.GetInt32(0), myReader.GetString(1));
myReader.Close();myReader.Close();
38 / 70
XmlReaderXmlReader• ExecuteXmlReader() FOR XMLExecuteXmlReader() FOR XML
[Visual Basic]
Dim custCMD As SqlCommand = New SqlCommand("SELECT * FROM Customers FOR XML _ AUTO, ELEMENTS", nwindConn)
Dim myXR As System.Xml.XmlReader = custCMD.ExecuteXmlReader()
[C#]
SqlCommand custCMD = new SqlCommand("SELECT * FROM Customers FOR XML AUTO, ELEMENTS", nwindConn);
System.Xml.XmlReader myXR = custCMD.ExecuteXmlReader();
39 / 70
Operazioni di Data Definition Operazioni di Data Definition LanguageLanguage
• ExecuteNonQuery()ExecuteNonQuery()
40 / 70
Transazioni in ADO.NETTransazioni in ADO.NET• Transazioni localiTransazioni locali
– All’interno del codice SQL delle Stored All’interno del codice SQL delle Stored ProcedureProcedure• BEGIN/COMMIT TRANBEGIN/COMMIT TRAN
– SqlOleDbTransactionSqlOleDbTransaction
41 / 70
Transazioni in ADO.NETTransazioni in ADO.NET
[C#]
SqlConnection conn = new SqlConnection();
conn.Open("...");
SqlTransaction tx = conn.BeginTransaction();
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = "...";
cmd.Transaction = tx;
cmd.ExecuteNonQuery();
tx.Commit();
[VB.NET]
OleDbConnection conn = new OleDbConnection();
conn.Open("...");
OleDbTransaction tx = conn.BeginTransaction();
OleDbCommand cmd = conn.CreateCommand();
cmd.CommandText = "...";
cmd.Transaction = tx;
cmd.ExecuteNonQuery();
tx.Commit();
42 / 70
Error & Info handlingError & Info handling
• Errori durante l’esecuzione di Errori durante l’esecuzione di operazioni sulla fonte dati vengono operazioni sulla fonte dati vengono intercettati attraverso le eccezioniintercettati attraverso le eccezioni
• Ogni Managed providers Ogni Managed providers implementa le proprie eccezioniimplementa le proprie eccezioni– SqlExceptionSqlException
• SqlErrorSqlError
43 / 70
Error & Info handlingError & Info handling
• SqlInfoMessageEventHandlerInfoMSqlInfoMessageEventHandlerInfoMessageessage
44 / 70
Error & Info handlingError & Info handling
public static int Main(string[] args) {
try
{
SqlConnection conn = new SqlConnection(“ConnectionString”);
// Associo un event handler all’evento di InfoMessage
conn.InfoMessage += new SqlInfoMessageEventHandler(myHandler);
conn.Open();
}
catch (SqlException e) {
for (int i=0; i < e.Errors.Count; i++)
{
Console.WriteLine("Index #" + i + "\n Error: " + e.Errors[i].ToString() + "\n");
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
finally
{ conn.Close(); }
return 0;
}
45 / 70
Error & Info handlingError & Info handling
public static void myHandler(object conn, SqlInfoMessageEventArgs e)
{
Console.WriteLine("caught a SQL warning");
for (int i=0; i < e.Errors.Count; i++)
{
Console.WriteLine("Index#" + i + "\n" + "Warning:" + e.Errors[i].ToString() +
"\n");
}
}
46 / 70
Considerazioni sulle Considerazioni sulle performanceperformance
• Dispose()DataReaderDispose()DataReader
47 / 70
Considerazioni sulle Considerazioni sulle performanceperformance
• FOR XMLXmlReaderFOR XMLXmlReader
48 / 70
Considerazioni sulle Considerazioni sulle performanceperformance
• Tenere sempre presente il tipo di Tenere sempre presente il tipo di comando e di valori di ritornocomando e di valori di ritorno– Singola entità letta per chiave primariaSingola entità letta per chiave primaria
• Stored Procedure con parametri di ritornoStored Procedure con parametri di ritorno– Valore scalareValore scalare
• ExecuteScalar()ExecuteScalar()– DataReaderDataReader
49 / 70
Codice portabile tra più Data Provider
50 / 70
Integrare applicazioni .NET con altri database server
51 / 70
OleDb Managed ProviderOleDb Managed Provider
52 / 70
OleDb Managed ProviderOleDb Managed Provider
Common Language RuntimeCommon Language Runtime
Data SourceData Source
RelazionaleRelazionale
e none non
OleDbOleDb
ManagedManaged
ProviderProvider
Pro
vid
er
Pro
vid
er
OLED
BO
LED
B
53 / 70
OLEDB Managed Provider OLEDB Managed Provider Object ModelObject Model
OleDbConnection
OleDbCommand
OleDbParameterCollectionOleDbDataReader
.Connection
.OleDbParameter
.CreateCommand
.Parameters
.Item
.Add
.CreateParameter
.ExecuteReader
Object
.Item
54 / 70
OleDbConnectionOleDbConnection
[Visual Basic][Visual Basic]
Dim myConnection As String = "Provider=SQLOLEDB;Data Source=localhost;Initial _ Dim myConnection As String = "Provider=SQLOLEDB;Data Source=localhost;Initial _ Catalog=Northwind;Integrated Security=SSPI;"Catalog=Northwind;Integrated Security=SSPI;"
Dim myConn As New OleDbConnection(myConnection)Dim myConn As New OleDbConnection(myConnection)
myConn.Open()myConn.Open()
[C#][C#]
String myConnection = "Provider=SQLOLEDB;Data Source=localhost;Initial String myConnection = "Provider=SQLOLEDB;Data Source=localhost;Initial Catalog=Northwind;Integrated Security=SSPI;";Catalog=Northwind;Integrated Security=SSPI;";
OleDbConnection myConn = new OleDbConnection(myConnection);OleDbConnection myConn = new OleDbConnection(myConnection);
myConn.Open();myConn.Open();
55 / 70
OleDbCommandOleDbCommand
public void ReadMyData(string myConnString) public void ReadMyData(string myConnString)
{{
string mySelectQuery = "SELECT OrderID, CustomerID FROM Orders";string mySelectQuery = "SELECT OrderID, CustomerID FROM Orders";
OleDbConnection myConnection = new OleDbConnection(myConnString);OleDbConnection myConnection = new OleDbConnection(myConnString);
OleDbCommand myCommand = new OleDbCommand(mySelectQuery,myConnection);OleDbCommand myCommand = new OleDbCommand(mySelectQuery,myConnection);
myConnection.Open();myConnection.Open();
OleDbDataReader myReader = myCommand.ExecuteReader();OleDbDataReader myReader = myCommand.ExecuteReader();
try try
{ {
while (myReader.Read()) while (myReader.Read())
{Console.WriteLine(myReader.GetInt32(0) + ", " + myReader.GetString(1));}{Console.WriteLine(myReader.GetInt32(0) + ", " + myReader.GetString(1));}
}}
finally finally
{{
// da chiudere sempre dopo aver terminato la lettura// da chiudere sempre dopo aver terminato la lettura
myReader.Close();myReader.Close();
// da chiudere sempre dopo aver terminato la lettura// da chiudere sempre dopo aver terminato la lettura
myConnection.Close();}myConnection.Close();}
}}
56 / 70
ODBC Managed ProviderODBC Managed Provider
57 / 70
ODBC Managed ProviderODBC Managed Provider
Common Language RuntimeCommon Language Runtime
Data SourceData Source
RelazionaleRelazionale
OdbcOdbc
ManagedManaged
ProviderProvider
Dri
ver
Dri
ver
OD
BC
OD
BC
58 / 70
ODBC Managed Provider ODBC Managed Provider Object ModelObject Model
OdbcConnection
OdbcCommand
OdbcParameterCollectionOdbcDataReader
.Connection
OdbcParameter
.CreateCommand
.Parameters
.Item
.Add
.CreateParameter
.ExecuteReader
Object
.Item
59 / 70
OleDbDataReaderOleDbDataReader
• ExecuteReader()ExecuteReader()
60 / 70
Utilizzo di OleDbDataReaderUtilizzo di OleDbDataReader
Public Sub ReadMyData(myConnString As String)
Dim mySelectQuery As String = "SELECT OrderID, CustomerID FROM Orders"
Dim myConnection As New OleDbConnection(myConnString)
Dim myCommand As New OleDbCommand(mySelectQuery, myConnection)
myConnection.Open()
Dim myReader As OleDbDataReader
myReader = myCommand.ExecuteReader()
' La chiamata a Read posiziona sul primo record
While myReader.Read()
Console.WriteLine(myReader.GetInt32(0).ToString() + ", " _
+ myReader.GetString(1))
End While
' chiudere il reader
myReader.Close()
' chiudere la connessione
myConnection.Close()
End Sub
61 / 70
DB2 e ADO.NET
ODBC .Net Data ODBC .Net Data ProviderProvider
OdbcConnectionOdbcConnection
OdbcCommandOdbcCommand
OdbcDataAdapterOdbcDataAdapter
OdbcDataReaderOdbcDataReader
OLE DB .Net OLE DB .Net Data ProviderData Provider
OleDbConnectionOleDbConnection
OleDbCommandOleDbCommand
OleDbAdapterOleDbAdapter
OleDbDataReaderOleDbDataReader
DB2 .Net Data DB2 .Net Data ProviderProvider
DB2ConnectionDB2Connection
DB2CommandDB2Command
DB2DataAdapterDB2DataAdapter
DB2DataReaderDB2DataReader
IBM DB2 ODBC IBM DB2 ODBC DriverDriver
IBM DB2 OLE IBM DB2 OLE DB ProviderDB Provider
ApplicationApplicationSystem.Data.OleDbSystem.Data.OleDb
ApplicationApplicationMicrosft.Data.ODBCMicrosft.Data.ODBC
ApplicationApplicationIBM.Data.DB2IBM.Data.DB2
DB2DB2
62 / 70
DB2Connection Object
63 / 70
DB2Command Object
64 / 70
DB2DataReader Object
65 / 70
Oracle e .NET
• Microsoft .NET Data Provider per Oracle– Prodotto da Microsoft– Usa gli strumenti client di Oracle
• Oracle Data Provider per .NET (ODP.NET)– Sviluppato da Oracle– Integrazione completa– Espone tutte le caratteristiche di un Oracle
DB• Oracle Connect per .NET
66 / 70
.NET Data Providers
67 / 70
ODP.NET
DataSet OracleDataAdapter
OracleTransaction
OracleCommand
OracleConnection
OracleDataReader
OracleCommandBuilder
68 / 70
ODP.NET
69 / 70
In Sintesi
70 / 70
Link utili
71 / 70
News
72 / 70