ado .net 2.0: what’s new

37
ADO .NET 2.0: what’s new ADO .NET 2.0: what’s new Andrea Saltarello Andrea Saltarello Software Architect – Software Architect – Managed Designs S.r.l. http:// blogs.ugidotnet.org / pape

Upload: hall-lee

Post on 31-Dec-2015

35 views

Category:

Documents


6 download

DESCRIPTION

ADO .NET 2.0: what’s new. Andrea Saltarello Software Architect – Managed Designs S.r.l. http://blogs.ugidotnet.org/pape. Sponsor. Parliamo di…. Architettura ADO .NET 2.0 System.Data: what’s new SqlClient enhancements M.A.R.S. Inizialmente annunciato come parte di ADO .NET 2.0… - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: ADO .NET 2.0: what’s new

ADO .NET 2.0: what’s newADO .NET 2.0: what’s newADO .NET 2.0: what’s newADO .NET 2.0: what’s new

Andrea SaltarelloAndrea SaltarelloSoftware Architect – Software Architect – Managed Designs S.r.l.http://blogs.ugidotnet.org/pape

Page 2: ADO .NET 2.0: what’s new

SponsorSponsor

Page 3: ADO .NET 2.0: what’s new

Parliamo di…Parliamo di…Parliamo di…Parliamo di…

• Architettura ADO .NET 2.0Architettura ADO .NET 2.0

• System.Data: what’s newSystem.Data: what’s new

• SqlClient enhancementsSqlClient enhancements

• M.A.R.S.M.A.R.S.

• Architettura ADO .NET 2.0Architettura ADO .NET 2.0

• System.Data: what’s newSystem.Data: what’s new

• SqlClient enhancementsSqlClient enhancements

• M.A.R.S.M.A.R.S.

Page 4: ADO .NET 2.0: what’s new

Agenda – Non parliamo di…Agenda – Non parliamo di…Agenda – Non parliamo di…Agenda – Non parliamo di…

• Inizialmente annunciato come parte di ADO .NET Inizialmente annunciato come parte di ADO .NET 2.0…2.0…

• E’ stato poi “agganciato” al rilascio di WinFS E’ stato poi “agganciato” al rilascio di WinFS (Longhorn)…(Longhorn)…

• Ma WinFS è stato “tagliato” da Longhorn e Ma WinFS è stato “tagliato” da Longhorn e posticipato a data da definirsi…posticipato a data da definirsi…

• Insomma… non ne parliamo Insomma… non ne parliamo

• Inizialmente annunciato come parte di ADO .NET Inizialmente annunciato come parte di ADO .NET 2.0…2.0…

• E’ stato poi “agganciato” al rilascio di WinFS E’ stato poi “agganciato” al rilascio di WinFS (Longhorn)…(Longhorn)…

• Ma WinFS è stato “tagliato” da Longhorn e Ma WinFS è stato “tagliato” da Longhorn e posticipato a data da definirsi…posticipato a data da definirsi…

• Insomma… non ne parliamo Insomma… non ne parliamo

ObjectSpacesObjectSpacesObjectSpacesObjectSpaces

Page 5: ADO .NET 2.0: what’s new

Prerequisiti per ADO .NET Prerequisiti per ADO .NET 2.02.0

Prerequisiti per ADO .NET Prerequisiti per ADO .NET 2.02.0

• Non necessitano di MDAC:Non necessitano di MDAC:• Classi base, comuni (System.Data.Common) e Classi base, comuni (System.Data.Common) e

disconnessedisconnesse• .NET managed provider per SQL Server e Oracle.NET managed provider per SQL Server e Oracle

• Usano MDAC, senza particolari Usano MDAC, senza particolari requisiti:requisiti:• Managed provider OLEDB e ODBCManaged provider OLEDB e ODBC• Vanno bene le versioni 2.6, 2.7, 2.8 o… 9.0Vanno bene le versioni 2.6, 2.7, 2.8 o… 9.0

• Non necessitano di MDAC:Non necessitano di MDAC:• Classi base, comuni (System.Data.Common) e Classi base, comuni (System.Data.Common) e

disconnessedisconnesse• .NET managed provider per SQL Server e Oracle.NET managed provider per SQL Server e Oracle

• Usano MDAC, senza particolari Usano MDAC, senza particolari requisiti:requisiti:• Managed provider OLEDB e ODBCManaged provider OLEDB e ODBC• Vanno bene le versioni 2.6, 2.7, 2.8 o… 9.0Vanno bene le versioni 2.6, 2.7, 2.8 o… 9.0

Page 6: ADO .NET 2.0: what’s new

Common Provider ModelCommon Provider ModelCommon Provider ModelCommon Provider Model

• ADO.NET v1.0/1.1 è basato su alcune ADO.NET v1.0/1.1 è basato su alcune interfacceinterfacce• E’ problematico scrivere codice indipendente dalla E’ problematico scrivere codice indipendente dalla

base datibase dati

• ADO .NET 2.0 è basato su classi base ADO .NET 2.0 è basato su classi base condivise dai providercondivise dai provider• E’ una estensione, non introduce incompatibilitàE’ una estensione, non introduce incompatibilità• La sintassi SQL è comunque La sintassi SQL è comunque specificaspecifica per la base dati! per la base dati!• Architettura basata sul pattern FactoryArchitettura basata sul pattern Factory

• ADO.NET v1.0/1.1 è basato su alcune ADO.NET v1.0/1.1 è basato su alcune interfacceinterfacce• E’ problematico scrivere codice indipendente dalla E’ problematico scrivere codice indipendente dalla

base datibase dati

• ADO .NET 2.0 è basato su classi base ADO .NET 2.0 è basato su classi base condivise dai providercondivise dai provider• E’ una estensione, non introduce incompatibilitàE’ una estensione, non introduce incompatibilità• La sintassi SQL è comunque La sintassi SQL è comunque specificaspecifica per la base dati! per la base dati!• Architettura basata sul pattern FactoryArchitettura basata sul pattern Factory

Page 7: ADO .NET 2.0: what’s new

ADO .NET 2: ArchitetturaADO .NET 2: ArchitetturaADO .NET 2: ArchitetturaADO .NET 2: ArchitetturaIDb* interfaces (es: IDbConnection)IDb* interfaces (es: IDbConnection)

Db* abstract base classes (es: DbConnection)Db* abstract base classes (es: DbConnection)

Db*Base implementation classesDb*Base implementation classes

SqlSql OleDbOleDb ODBCODBC OracleOracle 33rdrd Party 1Party 1

33rdrd Party 2Party 2

Layer Provider-Independent

Layer Provider-specific

Page 8: ADO .NET 2.0: what’s new

Classi Provider-independentClassi Provider-independentClassi Provider-independentClassi Provider-independent

Sono definite nel namespace System.Data.CommonSono definite nel namespace System.Data.Common– ad esempio:ad esempio:

Sono definite nel namespace System.Data.CommonSono definite nel namespace System.Data.Common– ad esempio:ad esempio:

DbCommandDbCommand DbCommandBuilderDbCommandBuilder DbConnectionDbConnection

DataAdapterDataAdapter DbDataAdapterDbDataAdapter DbDataReaderDbDataReader

DbParameterDbParameter DbParameterCollectionDbParameterCollection DbTransactionDbTransaction

DbProviderFactoryDbProviderFactory DbProviderFactoriesDbProviderFactories DbExceptionDbException

Page 9: ADO .NET 2.0: what’s new

Usare una Provider FactoryUsare una Provider FactoryUsare una Provider FactoryUsare una Provider Factory• Importare il Namespace:Importare il Namespace:

using System.Data.Commonusing System.Data.Common

• Creare l’istanza della Factory:Creare l’istanza della Factory:static DbProviderFactory factory = static DbProviderFactory factory = DbProviderFactories.GetFactory("provider-name")DbProviderFactories.GetFactory("provider-name")

• Creare le istanze degli oggetti:Creare le istanze degli oggetti:DbConnection con = factory.CreateConnection()DbConnection con = factory.CreateConnection()

DbCommand cmd = con.CreateCommand()DbCommand cmd = con.CreateCommand()

• Importare il Namespace:Importare il Namespace:using System.Data.Commonusing System.Data.Common

• Creare l’istanza della Factory:Creare l’istanza della Factory:static DbProviderFactory factory = static DbProviderFactory factory = DbProviderFactories.GetFactory("provider-name")DbProviderFactories.GetFactory("provider-name")

• Creare le istanze degli oggetti:Creare le istanze degli oggetti:DbConnection con = factory.CreateConnection()DbConnection con = factory.CreateConnection()

DbCommand cmd = con.CreateCommand()DbCommand cmd = con.CreateCommand()

Page 10: ADO .NET 2.0: what’s new

Provider EnumerationProvider EnumerationProvider EnumerationProvider Enumeration

• Ogni provider ha un nome invarianteOgni provider ha un nome invariante– Per esempio: "System.Data.SqlClient", "System.Data.OracleClient"Per esempio: "System.Data.SqlClient", "System.Data.OracleClient"

• Ottenere la lista delle provider factory Ottenere la lista delle provider factory installateinstallateDataTable dt = DataTable dt = DbProviderFactories.GetFactoryClasses()DbProviderFactories.GetFactoryClasses()

DbProviderFactory factory = DbProviderFactory factory = DbProviderFactories.GetFactory(dt.Rows[x])DbProviderFactories.GetFactory(dt.Rows[x])

– ... o ...... o ...DbProviderFactory factory = DbProviderFactory factory = DbProviderFactories.GetFactory( dt.Select("InvariDbProviderFactories.GetFactory( dt.Select("InvariantName='System.Data.SqlClient'") [0]antName='System.Data.SqlClient'") [0]["InvariantName"].ToString());["InvariantName"].ToString());

• Ogni provider ha un nome invarianteOgni provider ha un nome invariante– Per esempio: "System.Data.SqlClient", "System.Data.OracleClient"Per esempio: "System.Data.SqlClient", "System.Data.OracleClient"

• Ottenere la lista delle provider factory Ottenere la lista delle provider factory installateinstallateDataTable dt = DataTable dt = DbProviderFactories.GetFactoryClasses()DbProviderFactories.GetFactoryClasses()

DbProviderFactory factory = DbProviderFactory factory = DbProviderFactories.GetFactory(dt.Rows[x])DbProviderFactories.GetFactory(dt.Rows[x])

– ... o ...... o ...DbProviderFactory factory = DbProviderFactory factory = DbProviderFactories.GetFactory( dt.Select("InvariDbProviderFactories.GetFactory( dt.Select("InvariantName='System.Data.SqlClient'") [0]antName='System.Data.SqlClient'") [0]["InvariantName"].ToString());["InvariantName"].ToString());

Page 11: ADO .NET 2.0: what’s new

Provider EnumerationProvider Enumeration

usando una Provider Factoryusando una Provider Factory

Provider EnumerationProvider Enumeration

usando una Provider Factoryusando una Provider Factory

Page 12: ADO .NET 2.0: what’s new

Performance ImprovementsPerformance ImprovementsPerformance ImprovementsPerformance Improvements• Indicizzazione interna delle righe. I tempi Indicizzazione interna delle righe. I tempi

di:di:– InsertInsert e e deletedelete crescono logaritmicamente crescono logaritmicamente– updateupdate rimangono quasi costanti rimangono quasi costanti

• Serializzazione binariaSerializzazione binaria– I DataSet I DataSet v1.xv1.x erano sempre serializzati in erano sempre serializzati in

XMLXML• Vantaggioso per lo scambio dati, ma penalizzante Vantaggioso per lo scambio dati, ma penalizzante

per le performanceper le performance– La v2.0 supporta la serializzazione binariaLa v2.0 supporta la serializzazione binaria

• È più veloce ed occupa meno spazioÈ più veloce ed occupa meno spazio• Basta usare: DataSet.RemotingFormat = Basta usare: DataSet.RemotingFormat =

SerializationFormat.BinarySerializationFormat.Binary

• Indicizzazione interna delle righe. I tempi Indicizzazione interna delle righe. I tempi di:di:– InsertInsert e e deletedelete crescono logaritmicamente crescono logaritmicamente– updateupdate rimangono quasi costanti rimangono quasi costanti

• Serializzazione binariaSerializzazione binaria– I DataSet I DataSet v1.xv1.x erano sempre serializzati in erano sempre serializzati in

XMLXML• Vantaggioso per lo scambio dati, ma penalizzante Vantaggioso per lo scambio dati, ma penalizzante

per le performanceper le performance– La v2.0 supporta la serializzazione binariaLa v2.0 supporta la serializzazione binaria

• È più veloce ed occupa meno spazioÈ più veloce ed occupa meno spazio• Basta usare: DataSet.RemotingFormat = Basta usare: DataSet.RemotingFormat =

SerializationFormat.BinarySerializationFormat.Binary

Page 13: ADO .NET 2.0: what’s new

Performance inserimento Performance inserimento righerighe

Performance inserimento Performance inserimento righerighe

0

5 0 0

1 0 0 0

1 5 0 0

2 0 0 0

2 5 0 0

3 0 0 0

3 5 0 0

4 0 0 0

0 1 0 0 0 0 2 0 0 0 0 3 0 0 0 0 4 0 0 0 0 5 0 0 0 0 6 0 0 0 0 7 0 0 0 0

N u m b e r o f R o w s

Tim

e i

n M

illi

se

co

nd

s

E v e re t tW h id b e y

Page 14: ADO .NET 2.0: what’s new

DataRow Insertion Perf ImprovementDataRow Insertion Perf ImprovementDataRow Insertion Perf ImprovementDataRow Insertion Perf Improvement

Page 15: ADO .NET 2.0: what’s new

Binary vs. XML SerializationBinary vs. XML SerializationBinary vs. XML SerializationBinary vs. XML Serialization

1 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0

R o w s i n D a t a S e t

End-

to-E

nd T

ime

(low

er is

be

tter

)

X m l

B i n a r y

Incrementi fino ad 80 xIncrementi fino ad 80 x

Page 16: ADO .NET 2.0: what’s new

Popolare un DataSetPopolare un DataSetPopolare un DataSetPopolare un DataSet

• DataAdapter.Fill(DataSet, "table-name")DataAdapter.Fill(DataSet, "table-name")– Nuovo: proprietà DataAdapter.FillLoadOption e Nuovo: proprietà DataAdapter.FillLoadOption e

AcceptChangesDuringUpdateAcceptChangesDuringUpdate

• Nuovo: metodo DataSet.LoadNuovo: metodo DataSet.Load– Load(DataReader [, load-option] [, tables-Load(DataReader [, load-option] [, tables-

array])array])

• Nuovo: LoadOption enumerationNuovo: LoadOption enumeration– PreserveCurrentValues | UpdateCurrentValues PreserveCurrentValues | UpdateCurrentValues

| OverwriteRow| OverwriteRow

• DataAdapter.Fill(DataSet, "table-name")DataAdapter.Fill(DataSet, "table-name")– Nuovo: proprietà DataAdapter.FillLoadOption e Nuovo: proprietà DataAdapter.FillLoadOption e

AcceptChangesDuringUpdateAcceptChangesDuringUpdate

• Nuovo: metodo DataSet.LoadNuovo: metodo DataSet.Load– Load(DataReader [, load-option] [, tables-Load(DataReader [, load-option] [, tables-

array])array])

• Nuovo: LoadOption enumerationNuovo: LoadOption enumeration– PreserveCurrentValues | UpdateCurrentValues PreserveCurrentValues | UpdateCurrentValues

| OverwriteRow| OverwriteRow

Page 17: ADO .NET 2.0: what’s new

LoadOption EnumerationLoadOption EnumerationLoadOption EnumerationLoadOption EnumerationRowState of RowState of Existing RowExisting Row

PreserveCurrentValuesPreserveCurrentValues(the default value)(the default value)

UpdateCurrentValuesUpdateCurrentValues OverwriteRow OverwriteRow

AddedAdded Current = ExistingCurrent = ExistingOriginal = IncomingOriginal = IncomingRowState = ModifiedRowState = Modified

Current = IncomingCurrent = IncomingOriginal = ExistingOriginal = ExistingRowState = AddedRowState = Added

Current = IncomingCurrent = IncomingOriginal = IncomingOriginal = IncomingRowState = UnchangedRowState = Unchanged

ModifiedModified Current = ExistingCurrent = ExistingOriginal = IncomingOriginal = IncomingRowState = ModifiedRowState = Modified

Current = IncomingCurrent = IncomingOriginal = ExistingOriginal = ExistingRowState = ModifiedRowState = Modified

Current = IncomingCurrent = IncomingOriginal = IncomingOriginal = IncomingRowState = UnchangedRowState = Unchanged

DeletedDeleted Current = ExistingCurrent = ExistingOriginal = IncomingOriginal = IncomingRowState = DeletedRowState = Deleted

* Undo Delete * Undo Delete Current = IncomingCurrent = IncomingOriginal = ExistingOriginal = ExistingRowState = ModifiedRowState = Modified

* Undo Delete * Undo Delete Current = IncomingCurrent = IncomingOriginal = IncomingOriginal = IncomingRowState = UnchangedRowState = Unchanged

UnchangedUnchanged Current = IncomingCurrent = IncomingOriginal = IncomingOriginal = IncomingRowState = UnchangedRowState = Unchanged

Current = IncomingCurrent = IncomingOriginal = ExistingOriginal = Existing* if new value = existing value: * if new value = existing value: RowState = Unchanged RowState = Unchanged * else:* else: RowState = ModifiedRowState = Modified

Current = IncomingCurrent = IncomingOriginal = IncomingOriginal = IncomingRowState = UnchangedRowState = Unchanged

No matching No matching existing row in the existing row in the tabletable

Current = IncomingCurrent = IncomingOriginal = IncomingOriginal = IncomingRowState = UnchangedRowState = Unchanged

Current = IncomingCurrent = IncomingOriginal = ExistingOriginal = ExistingRowState = AddedRowState = Added

Current = IncomingCurrent = IncomingOriginal = IncomingOriginal = IncomingRowState = UnchangedRowState = Unchanged

Page 18: ADO .NET 2.0: what’s new

Nuove featureNuove featureNuove featureNuove feature

• RowState modificabileRowState modificabile

– Nuovi metodi: DataRow.SetAdded e Nuovi metodi: DataRow.SetAdded e

DataRow.SetModifiedDataRow.SetModified

• Metodo DataSet.GetDataReaderMetodo DataSet.GetDataReader

– Restituisce un DataTableReaderRestituisce un DataTableReader

– E’ possibile specificare quali tabelle includereE’ possibile specificare quali tabelle includere

• RowState modificabileRowState modificabile

– Nuovi metodi: DataRow.SetAdded e Nuovi metodi: DataRow.SetAdded e

DataRow.SetModifiedDataRow.SetModified

• Metodo DataSet.GetDataReaderMetodo DataSet.GetDataReader

– Restituisce un DataTableReaderRestituisce un DataTableReader

– E’ possibile specificare quali tabelle includereE’ possibile specificare quali tabelle includere

Page 19: ADO .NET 2.0: what’s new

Popolare un DataSet con un DataReader Popolare un DataSet con un DataReader e usare un DataTableReader.e usare un DataTableReader.

Popolare un DataSet con un DataReader Popolare un DataSet con un DataReader e usare un DataTableReader.e usare un DataTableReader.

Page 20: ADO .NET 2.0: what’s new

DataTable “stand-alone”DataTable “stand-alone”DataTable “stand-alone”DataTable “stand-alone”• Operazioni tipiche del DataSet supportate anche Operazioni tipiche del DataSet supportate anche

per le DataTable:per le DataTable:

– ReadXml, ReadXmlSchema, WriteXml, ReadXml, ReadXmlSchema, WriteXml,

WriteXmlSchema, Clear, Clone, Copy, Merge, WriteXmlSchema, Clear, Clone, Copy, Merge,

GetChanges GetChanges

• La classe DataTable ora supporta la La classe DataTable ora supporta la

serializzazione:serializzazione:

– Perchè implementa Perchè implementa IXmlSerializableIXmlSerializable

– E’ possibile restituire una istanza di DataTable mediante E’ possibile restituire una istanza di DataTable mediante

Web Service o RemotingWeb Service o Remoting

• Operazioni tipiche del DataSet supportate anche Operazioni tipiche del DataSet supportate anche

per le DataTable:per le DataTable:

– ReadXml, ReadXmlSchema, WriteXml, ReadXml, ReadXmlSchema, WriteXml,

WriteXmlSchema, Clear, Clone, Copy, Merge, WriteXmlSchema, Clear, Clone, Copy, Merge,

GetChanges GetChanges

• La classe DataTable ora supporta la La classe DataTable ora supporta la

serializzazione:serializzazione:

– Perchè implementa Perchè implementa IXmlSerializableIXmlSerializable

– E’ possibile restituire una istanza di DataTable mediante E’ possibile restituire una istanza di DataTable mediante

Web Service o RemotingWeb Service o Remoting

Page 21: ADO .NET 2.0: what’s new

Popolare ed usare DataTablePopolare ed usare DataTablePopolare ed usare DataTablePopolare ed usare DataTable

• DataAdapter.Fill(DataTable)DataAdapter.Fill(DataTable)

• DataAdapter.Fill(DataTable[ ], …)DataAdapter.Fill(DataTable[ ], …)– Permette di selezionare un sottoinsieme di righePermette di selezionare un sottoinsieme di righe

• DataAdapter.Update(DataTable)DataAdapter.Update(DataTable)

• DataTable.Load(DataReader [, load-option] DataTable.Load(DataReader [, load-option] [, FillErrorEventHandler])[, FillErrorEventHandler])– Nuovi metodi: BeginLoadData, Load, EndLoadDataNuovi metodi: BeginLoadData, Load, EndLoadData

• DataTable.GetDataReader methodDataTable.GetDataReader method– Ottiene uno stream da una DataTableOttiene uno stream da una DataTable

• DataAdapter.Fill(DataTable)DataAdapter.Fill(DataTable)

• DataAdapter.Fill(DataTable[ ], …)DataAdapter.Fill(DataTable[ ], …)– Permette di selezionare un sottoinsieme di righePermette di selezionare un sottoinsieme di righe

• DataAdapter.Update(DataTable)DataAdapter.Update(DataTable)

• DataTable.Load(DataReader [, load-option] DataTable.Load(DataReader [, load-option] [, FillErrorEventHandler])[, FillErrorEventHandler])– Nuovi metodi: BeginLoadData, Load, EndLoadDataNuovi metodi: BeginLoadData, Load, EndLoadData

• DataTable.GetDataReader methodDataTable.GetDataReader method– Ottiene uno stream da una DataTableOttiene uno stream da una DataTable

Page 22: ADO .NET 2.0: what’s new

Update BatchUpdate BatchUpdate BatchUpdate Batch

• In 1.1, gli update dei DataSet sono eseguiti In 1.1, gli update dei DataSet sono eseguiti riga per rigariga per riga

• Il batch update riduce round-trip lungo la Il batch update riduce round-trip lungo la reterete

• DataAdapter.UpdateBatchSize = DataAdapter.UpdateBatchSize = batch_sizebatch_size

• Funziona all’interno di transazioniFunziona all’interno di transazioni• Funziona con SQL Server 7.0, 2000, 2005Funziona con SQL Server 7.0, 2000, 2005• Disponibile anche per il provider Disponibile anche per il provider

OracleClientOracleClient

• In 1.1, gli update dei DataSet sono eseguiti In 1.1, gli update dei DataSet sono eseguiti riga per rigariga per riga

• Il batch update riduce round-trip lungo la Il batch update riduce round-trip lungo la reterete

• DataAdapter.UpdateBatchSize = DataAdapter.UpdateBatchSize = batch_sizebatch_size

• Funziona all’interno di transazioniFunziona all’interno di transazioni• Funziona con SQL Server 7.0, 2000, 2005Funziona con SQL Server 7.0, 2000, 2005• Disponibile anche per il provider Disponibile anche per il provider

OracleClientOracleClient

Page 23: ADO .NET 2.0: what’s new

DataTable “stand-alone”DataTable “stand-alone”DataTable “stand-alone”DataTable “stand-alone”

Page 24: ADO .NET 2.0: what’s new

Comandi asincroniComandi asincroniComandi asincroniComandi asincroni

• Ideali per eseguire molteplici queryIdeali per eseguire molteplici query• Il “solito” Async Pattern: Il “solito” Async Pattern: BeginBeginxxxxxx e e EndEndxxxxxx

• Supporta Polling, Wait e CallbackSupporta Polling, Wait e Callback• Non dovrebbe essere usato in abbinamento Non dovrebbe essere usato in abbinamento

a MARSa MARS– usate una connessione per ogni Commandusate una connessione per ogni Command

• Aggiungere "async=true" alla connection Aggiungere "async=true" alla connection stringstring

• Ideali per eseguire molteplici queryIdeali per eseguire molteplici query• Il “solito” Async Pattern: Il “solito” Async Pattern: BeginBeginxxxxxx e e EndEndxxxxxx

• Supporta Polling, Wait e CallbackSupporta Polling, Wait e Callback• Non dovrebbe essere usato in abbinamento Non dovrebbe essere usato in abbinamento

a MARSa MARS– usate una connessione per ogni Commandusate una connessione per ogni Command

• Aggiungere "async=true" alla connection Aggiungere "async=true" alla connection stringstring

Page 25: ADO .NET 2.0: what’s new

~ 3 secs

Application

Esecuzione sincronaEsecuzione sincronaEsecuzione sincronaEsecuzione sincrona

Rowset 1

Rowset 2

Rowset 3

Tempo per visualizzare i dati:

Database2Latency 8 secs

Database3Latency 5 secs

Connection

Connection

~ 11 secs ~ 16 secs

Data 1

Data 1

Data 1Data 1Data 1

Data 1

Data 1

Data 1

Data 1

Data 1Data 1Data 1

Data 1

Data 1

Data 1

Data 1

Data 1Data 1Data 1

Data 1

Data 1

Data 1

Data 1

Data 1Data 1Data 1

Data 1

Data 1

Data 1

Data 1

Data 1Data 1Data 1

Data 1

Data 1

Data 1

Data 1

Data 1Data 1Data 1

Data 1

Data 1

Data 1

Data 1

Data 1Data 1Data 1

Data 1

Data 1

Data 1

Data 1

Data 1Data 1Data 1

Data 1

Data 1

Data 1

Data 1

Data 1Data 1Data 1

Data 1

Data 1

Data 1

Data 1

Data 1Data 1Data 1

Data 1

Data 1

Data 1

Data 1

Data 1Data 1Data 1

Data 1

Data 1

Data 1

Data 1

Data 1Data 1Data 1

Data 1

Data 1

Database1Latency 3 secsConnection

Page 26: ADO .NET 2.0: what’s new

Application

Esecuzione asincronaEsecuzione asincronaEsecuzione asincronaEsecuzione asincrona

Rowset 1

Rowset 2

Rowset 3

Connection1

Connection2

Connection3

~ 8 secs Tempo per visualizzare i dati:

Data 1

Data 1

Data 1Data 1Data 1

Data 1

Data 1

Data 1

Data 1

Data 1Data 1Data 1

Data 1

Data 1

Data 1

Data 1

Data 1Data 1Data 1

Data 1

Data 1

Data 1

Data 1

Data 1Data 1Data 1

Data 1

Data 1

Data 1

Data 1

Data 1Data 1Data 1

Data 1

Data 1

Data 1

Data 1

Data 1Data 1Data 1

Data 1

Data 1

Data 1

Data 1

Data 1Data 1Data 1

Data 1

Data 1

Data 1

Data 1

Data 1Data 1Data 1

Data 1

Data 1

Data 1

Data 1

Data 1Data 1Data 1

Data 1

Data 1

Data 1

Data 1

Data 1Data 1Data 1

Data 1

Data 1

Data 1

Data 1

Data 1Data 1Data 1

Data 1

Data 1

Data 1

Data 1

Data 1Data 1Data 1

Data 1

Data 1

Database1Latency 3 secs

Database2Latency 8 secs

Database3Latency 5 secs

Page 27: ADO .NET 2.0: what’s new

Esecuzione asincrona: Esecuzione asincrona: Polling ModelPolling Model

Esecuzione asincrona: Esecuzione asincrona: Polling ModelPolling Model

• Avviare un comando asincrono:Avviare un comando asincrono:Dim result As IAsyncResult = Dim result As IAsyncResult = MyCommand.BeginExecuteReader()MyCommand.BeginExecuteReader()

• Aspettare fino al termine della Aspettare fino al termine della esecuzione:esecuzione:While Not result.IsCompletedWhile Not result.IsCompleted

‘‘Codice da eseguireCodice da eseguire

End WhileEnd While

• Recuperare i risultati:Recuperare i risultati:Dim reader As SqlDataReader = Dim reader As SqlDataReader = MyCommand.EndExecuteReader(result )MyCommand.EndExecuteReader(result )

• Avviare un comando asincrono:Avviare un comando asincrono:Dim result As IAsyncResult = Dim result As IAsyncResult = MyCommand.BeginExecuteReader()MyCommand.BeginExecuteReader()

• Aspettare fino al termine della Aspettare fino al termine della esecuzione:esecuzione:While Not result.IsCompletedWhile Not result.IsCompleted

‘‘Codice da eseguireCodice da eseguire

End WhileEnd While

• Recuperare i risultati:Recuperare i risultati:Dim reader As SqlDataReader = Dim reader As SqlDataReader = MyCommand.EndExecuteReader(result )MyCommand.EndExecuteReader(result )

Page 28: ADO .NET 2.0: what’s new

Esecuzione asincrona: Wait Esecuzione asincrona: Wait (All) Model(All) Model

Esecuzione asincrona: Wait Esecuzione asincrona: Wait (All) Model(All) Model

• Avviare uno o più comandi asincroni:Avviare uno o più comandi asincroni:Dim resultDim resultxx As IAsyncResult = As IAsyncResult = MyCommand.BeginExecuteReader()MyCommand.BeginExecuteReader()

• Attendere il completamento di tutti i Attendere il completamento di tutti i comandi:comandi:WaitHandle.WaitAll(New WaitHandle() WaitHandle.WaitAll(New WaitHandle() {result1.AsyncWaitHandle, {result1.AsyncWaitHandle, result2.AsyncWaitHandle, result2.AsyncWaitHandle, result3.AsyncWaitHandle}, timeout - ms, True)result3.AsyncWaitHandle}, timeout - ms, True)

• Recuperare i risultati:Recuperare i risultati:Dim reader As SqlDataReader = Dim reader As SqlDataReader = MyCommand.EndExecuteReader(resultMyCommand.EndExecuteReader(resultxx))

• Ideale per le Web Application ASP.NETIdeale per le Web Application ASP.NET

• Avviare uno o più comandi asincroni:Avviare uno o più comandi asincroni:Dim resultDim resultxx As IAsyncResult = As IAsyncResult = MyCommand.BeginExecuteReader()MyCommand.BeginExecuteReader()

• Attendere il completamento di tutti i Attendere il completamento di tutti i comandi:comandi:WaitHandle.WaitAll(New WaitHandle() WaitHandle.WaitAll(New WaitHandle() {result1.AsyncWaitHandle, {result1.AsyncWaitHandle, result2.AsyncWaitHandle, result2.AsyncWaitHandle, result3.AsyncWaitHandle}, timeout - ms, True)result3.AsyncWaitHandle}, timeout - ms, True)

• Recuperare i risultati:Recuperare i risultati:Dim reader As SqlDataReader = Dim reader As SqlDataReader = MyCommand.EndExecuteReader(resultMyCommand.EndExecuteReader(resultxx))

• Ideale per le Web Application ASP.NETIdeale per le Web Application ASP.NET

Page 29: ADO .NET 2.0: what’s new

Esecuzione asincrona: Wait Esecuzione asincrona: Wait (Any) Model(Any) Model

Esecuzione asincrona: Wait Esecuzione asincrona: Wait (Any) Model(Any) Model

• Avviare uno o più comandi asincroni come array di Avviare uno o più comandi asincroni come array di istanze di IAsyncResult:istanze di IAsyncResult:Dim resultDim resultxx As IAsyncResult = As IAsyncResult =

MyCommand.BeginExecuteReader()MyCommand.BeginExecuteReader()

• Attendere il completamento di ogni comando:Attendere il completamento di ogni comando:Dim i As IntegerDim i As IntegerFor i = 0 To result_array.LengthFor i = 0 To result_array.Length

index = WaitHandle.WaitAny(result_array,index = WaitHandle.WaitAny(result_array, timeout, true)timeout, true)

Select Case indexSelect Case indexCase 0Case 0

Dim reader As SqlDataReader =Dim reader As SqlDataReader = MyCommand.EndExecuteReader(resultMyCommand.EndExecuteReader(resultxx))

......End SelectEnd Select

End ForEnd For

• Avviare uno o più comandi asincroni come array di Avviare uno o più comandi asincroni come array di istanze di IAsyncResult:istanze di IAsyncResult:Dim resultDim resultxx As IAsyncResult = As IAsyncResult =

MyCommand.BeginExecuteReader()MyCommand.BeginExecuteReader()

• Attendere il completamento di ogni comando:Attendere il completamento di ogni comando:Dim i As IntegerDim i As IntegerFor i = 0 To result_array.LengthFor i = 0 To result_array.Length

index = WaitHandle.WaitAny(result_array,index = WaitHandle.WaitAny(result_array, timeout, true)timeout, true)

Select Case indexSelect Case indexCase 0Case 0

Dim reader As SqlDataReader =Dim reader As SqlDataReader = MyCommand.EndExecuteReader(resultMyCommand.EndExecuteReader(resultxx))

......End SelectEnd Select

End ForEnd For

Page 30: ADO .NET 2.0: what’s new

Esecuzione asincrona: Esecuzione asincrona: Callback ModelCallback Model

Esecuzione asincrona: Esecuzione asincrona: Callback ModelCallback Model

• Avviare l’esecuzione, specificando la Avviare l’esecuzione, specificando la funzione di callback e il command come funzione di callback e il command come AsyncState:AsyncState:MyCommand.BeginExecuteReader(new MyCommand.BeginExecuteReader(new AsyncCallback(MyCallback), cmd)AsyncCallback(MyCallback), cmd)

• Creare il gestore del callback:Creare il gestore del callback:Sub MyCallback(ByVal result As IAsyncResult) Sub MyCallback(ByVal result As IAsyncResult)

Dim cmd As SqlCommand = Dim cmd As SqlCommand = DirectCast(result.AsyncState, SqlCommand)DirectCast(result.AsyncState, SqlCommand)

Dim reader As SqlDataReader = Dim reader As SqlDataReader = cmd.EndExecuteReader(result)cmd.EndExecuteReader(result)

End SubEnd Sub

• Avviare l’esecuzione, specificando la Avviare l’esecuzione, specificando la funzione di callback e il command come funzione di callback e il command come AsyncState:AsyncState:MyCommand.BeginExecuteReader(new MyCommand.BeginExecuteReader(new AsyncCallback(MyCallback), cmd)AsyncCallback(MyCallback), cmd)

• Creare il gestore del callback:Creare il gestore del callback:Sub MyCallback(ByVal result As IAsyncResult) Sub MyCallback(ByVal result As IAsyncResult)

Dim cmd As SqlCommand = Dim cmd As SqlCommand = DirectCast(result.AsyncState, SqlCommand)DirectCast(result.AsyncState, SqlCommand)

Dim reader As SqlDataReader = Dim reader As SqlDataReader = cmd.EndExecuteReader(result)cmd.EndExecuteReader(result)

End SubEnd Sub

Page 31: ADO .NET 2.0: what’s new

Esecuzione di comandi asincroniEsecuzione di comandi asincroniEsecuzione di comandi asincroniEsecuzione di comandi asincroni

Page 32: ADO .NET 2.0: what’s new

DataReader: PagingDataReader: PagingDataReader: PagingDataReader: Paging• Il paging? Il paging? C’est plus facileC’est plus facile, col metodo , col metodo

ExecutePageReaderExecutePageReader• Accetta l’indice della prima riga e il numero di righe da restituireAccetta l’indice della prima riga e il numero di righe da restituire

• Non garantisce consistenzaNon garantisce consistenza• Senza il supporto di una transazione, alcune righe potrebbero Senza il supporto di una transazione, alcune righe potrebbero

essere saltate o ripetuteessere saltate o ripetute

• Moooolto più veloce che leggere tutte le righe Moooolto più veloce che leggere tutte le righe ed ignorare quelle non desiderateed ignorare quelle non desiderate– E’ comunque preferibile eseguire una query “mirata”E’ comunque preferibile eseguire una query “mirata”

• Il paging? Il paging? C’est plus facileC’est plus facile, col metodo , col metodo ExecutePageReaderExecutePageReader• Accetta l’indice della prima riga e il numero di righe da restituireAccetta l’indice della prima riga e il numero di righe da restituire

• Non garantisce consistenzaNon garantisce consistenza• Senza il supporto di una transazione, alcune righe potrebbero Senza il supporto di una transazione, alcune righe potrebbero

essere saltate o ripetuteessere saltate o ripetute

• Moooolto più veloce che leggere tutte le righe Moooolto più veloce che leggere tutte le righe ed ignorare quelle non desiderateed ignorare quelle non desiderate– E’ comunque preferibile eseguire una query “mirata”E’ comunque preferibile eseguire una query “mirata”

Troppo bello per essere vero? Lo pensa anche Troppo bello per essere vero? Lo pensa anche Microsoft, infatti ha rimosso il metodo nella Microsoft, infatti ha rimosso il metodo nella beta2beta2

Troppo bello per essere vero? Lo pensa anche Troppo bello per essere vero? Lo pensa anche Microsoft, infatti ha rimosso il metodo nella Microsoft, infatti ha rimosso il metodo nella beta2beta2

Page 33: ADO .NET 2.0: what’s new

Multiple Active Result Sets Multiple Active Result Sets (MARS)(MARS)

Multiple Active Result Sets Multiple Active Result Sets (MARS)(MARS)

• (Ri)Conoscete questo messaggio? (Ri)Conoscete questo messaggio? – System.InvalidOperationException: There is System.InvalidOperationException: There is

already an open DataReader associated with this already an open DataReader associated with this Connection which must be closed first.Connection which must be closed first.

• (Ri)Conoscete questo messaggio? (Ri)Conoscete questo messaggio? – System.InvalidOperationException: There is System.InvalidOperationException: There is

already an open DataReader associated with this already an open DataReader associated with this Connection which must be closed first.Connection which must be closed first.

Page 34: ADO .NET 2.0: what’s new

Multiple Active Results Sets Multiple Active Results Sets (MARS)(MARS)

Multiple Active Results Sets Multiple Active Results Sets (MARS)(MARS)

• Mantiene disponibile una connessione Mantiene disponibile una connessione quando apriamo un SqlDataReader al fine quando apriamo un SqlDataReader al fine di poter:di poter:– Eseguire un’altra query per ottenere un Eseguire un’altra query per ottenere un

DataReader/XmlReaderDataReader/XmlReader– Eseguire comandi DMLEseguire comandi DML

• Possono essere attivi differenti result set Possono essere attivi differenti result set contemporaeamentecontemporaeamente– alternare fetch ad ogni readeralternare fetch ad ogni reader– Alternare query che non restituiscono readerAlternare query che non restituiscono reader

• Mantiene disponibile una connessione Mantiene disponibile una connessione quando apriamo un SqlDataReader al fine quando apriamo un SqlDataReader al fine di poter:di poter:– Eseguire un’altra query per ottenere un Eseguire un’altra query per ottenere un

DataReader/XmlReaderDataReader/XmlReader– Eseguire comandi DMLEseguire comandi DML

• Possono essere attivi differenti result set Possono essere attivi differenti result set contemporaeamentecontemporaeamente– alternare fetch ad ogni readeralternare fetch ad ogni reader– Alternare query che non restituiscono readerAlternare query che non restituiscono reader

Page 35: ADO .NET 2.0: what’s new

Alternare Results SetAlternare Results SetAlternare Results SetAlternare Results Set

• Scenario tipico:Scenario tipico:– Recuperare la lista dei clienti e scorrerlaRecuperare la lista dei clienti e scorrerla– Per ogni cliente, recuperare la lista degli ordiniPer ogni cliente, recuperare la lista degli ordini– Per ogni ordine, recuperarne il dettaglioPer ogni ordine, recuperarne il dettaglio

• Nella v1, per ottenere ciò usando dei reader Nella v1, per ottenere ciò usando dei reader erano necessarie differenti connessionierano necessarie differenti connessioni

• Mediante MARS, è sufficiente una sola Mediante MARS, è sufficiente una sola connessione se:connessione se:– I dati risiedono nello stesso databaseI dati risiedono nello stesso database– Usiamo SQL Server 2005/MDAC9Usiamo SQL Server 2005/MDAC9

• Scenario tipico:Scenario tipico:– Recuperare la lista dei clienti e scorrerlaRecuperare la lista dei clienti e scorrerla– Per ogni cliente, recuperare la lista degli ordiniPer ogni cliente, recuperare la lista degli ordini– Per ogni ordine, recuperarne il dettaglioPer ogni ordine, recuperarne il dettaglio

• Nella v1, per ottenere ciò usando dei reader Nella v1, per ottenere ciò usando dei reader erano necessarie differenti connessionierano necessarie differenti connessioni

• Mediante MARS, è sufficiente una sola Mediante MARS, è sufficiente una sola connessione se:connessione se:– I dati risiedono nello stesso databaseI dati risiedono nello stesso database– Usiamo SQL Server 2005/MDAC9Usiamo SQL Server 2005/MDAC9

Page 36: ADO .NET 2.0: what’s new

Interleaved Results Sets Interleaved Results Sets ExampleExample

Interleaved Results Sets Interleaved Results Sets ExampleExample

Dim parentReader As DataReader = Dim parentReader As DataReader = Command1.ExecuteReader()Command1.ExecuteReader()

While parentReader.Read()While parentReader.Read()

' process parent row data here' process parent row data here

' then get rowset from child table' then get rowset from child table

Command2.Parameters("@id").Value = Command2.Parameters("@id").Value = parentReader("id")parentReader("id")

Dim childReader As DataReader = Dim childReader As DataReader = Command2.ExecuteReader()Command2.ExecuteReader()

' process child rows here' process child rows here

childReader.Close()childReader.Close()

End WhileEnd While

parentReader.Close()parentReader.Close()

Dim parentReader As DataReader = Dim parentReader As DataReader = Command1.ExecuteReader()Command1.ExecuteReader()

While parentReader.Read()While parentReader.Read()

' process parent row data here' process parent row data here

' then get rowset from child table' then get rowset from child table

Command2.Parameters("@id").Value = Command2.Parameters("@id").Value = parentReader("id")parentReader("id")

Dim childReader As DataReader = Dim childReader As DataReader = Command2.ExecuteReader()Command2.ExecuteReader()

' process child rows here' process child rows here

childReader.Close()childReader.Close()

End WhileEnd While

parentReader.Close()parentReader.Close()

Page 37: ADO .NET 2.0: what’s new

LinksLinksLinksLinks

http://www.ugidotnet.org

http://forum.ugidotnet.org

http://mobile.ugidotnet.org