1 / 70 ado.net, i data provider e l'architettura connessa silvano coriani developer &...

Post on 01-May-2015

215 Views

Category:

Documents

1 Downloads

Preview:

Click to see full reader

TRANSCRIPT

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

top related