Data Access Changes in .Net 2.0Data Access Changes in .Net 2.0
David Truxall, Ph.D.David Truxall, Ph.D.Principal ConsultantPrincipal ConsultantNuSoft SolutionsNuSoft Solutions
AgendaAgenda
Enhancements to the DataSet classEnhancements to the DataSet class
SqlClient EnhancementsSqlClient EnhancementsAsynchronous CommandsAsynchronous Commands
SQL Cache DependencySQL Cache Dependency
SQL Server 2005 IntegrationSQL Server 2005 IntegrationMultiple Active Result SetsMultiple Active Result Sets
Generic Data StructuresGeneric Data StructuresList<T>List<T>
DictionaryDictionary
DataSet EnhancementsDataSet Enhancements
Performance and scalability Performance and scalability improvementsimprovements
Loading a DataSet, and the new Loading a DataSet, and the new LoadOption enumerationLoadOption enumeration
Stand-alone DataTable instancesStand-alone DataTable instances
Batched updatesBatched updates
XML data type - usability and fidelityXML data type - usability and fidelity
User-defined Types in a DataSetUser-defined Types in a DataSet
Performance Performance ImprovementsImprovements
Internal Indexing of RowsInternal Indexing of RowsInserts and deletes are log-nInserts and deletes are log-n
Updates almost constantUpdates almost constant
Binary Serialization of ContentsBinary Serialization of ContentsV 1.x DataSet always serialized to XMLV 1.x DataSet always serialized to XML
good for data interchange, bad for good for data interchange, bad for performanceperformance
Binary serialization an option in V 2.0Binary serialization an option in V 2.0fast and compact, especially as row counts fast and compact, especially as row counts increaseincrease
just set: DataSet.RemotingFormat = just set: DataSet.RemotingFormat = SerializationFormat.BinarySerializationFormat.Binary
Binary v XML SerializationBinary v XML Serialization
100 1000 10000 100000
Row s in DataSet
En
d-t
o-E
nd
Tim
e (l
ow
er is
bet
ter)
Xm l
Binary
Up to 80 x faster for large DataSets!Up to 80 x faster for large DataSets!
Loading a DataSetLoading a DataSet
DataAdapter.Fill(DataSet,"table-DataAdapter.Fill(DataSet,"table-name")name")
NEW: DataAdapter.FillLoadOption and NEW: DataAdapter.FillLoadOption and AcceptChangesDuringUpdate propertiesAcceptChangesDuringUpdate properties
NEW: DataSet.Load methodNEW: DataSet.Load methodLoad(DataReader [, load-option] [, tables-Load(DataReader [, load-option] [, tables-array])array])
optionally can use FillErrorEventHandler to optionally can use FillErrorEventHandler to trap errorstrap errors
NEW: LoadOption enumerationNEW: LoadOption enumerationPreserveCurrentValues | PreserveCurrentValues | UpdateCurrentValues | OverwriteRowUpdateCurrentValues | OverwriteRow
More New FeaturesMore New FeaturesRowState values are now updateableRowState values are now updateable
New methods: DataRow.SetAdded and New methods: DataRow.SetAdded and
DataRow.SetModifiedDataRow.SetModified
DataSet.GetDataReader methodDataSet.GetDataReader method
returns a DataTableReaderreturns a DataTableReader
you can specify which tables to includeyou can specify which tables to include
Loading a DataSet with a DataReaderLoading a DataSet with a DataReader
Binary SerializationBinary Serialization
Using a DataTableReaderUsing a DataTableReader
Stand-alone DataTable Stand-alone DataTable InstancesInstances
Common DataSet operations now also Common DataSet operations now also
available on DataTable:available on DataTable:
ReadXml, ReadXmlSchema, WriteXml, ReadXml, ReadXmlSchema, WriteXml,
WriteXmlSchema, Clear, Clone, Copy, WriteXmlSchema, Clear, Clone, Copy,
Merge, GetChanges Merge, GetChanges
DataTable is now auto-serializable:DataTable is now auto-serializable:
return a DataTable instance from a Web return a DataTable instance from a Web
Service or via RemotingService or via Remoting
Loading and Using a Loading and Using a DataTableDataTable
DataAdapter.Fill(DataTable)DataAdapter.Fill(DataTable)
DataAdapter.Fill(DataTable[ ])DataAdapter.Fill(DataTable[ ])and more, including subsets of rowsand more, including subsets of rows
DataAdapter.Update(DataTable)DataAdapter.Update(DataTable)
DataTable.Load(DataReader [, load-DataTable.Load(DataReader [, load-option] [, FillErrorEventHandler])option] [, FillErrorEventHandler])
new methods: BeginLoadData, Load, new methods: BeginLoadData, Load, EndLoadDataEndLoadData
DataTable.GetDataReader methodDataTable.GetDataReader methodstream data from a DataTablestream data from a DataTable
Batched UpdatesBatched UpdatesDataSet updates are normally DataSet updates are normally processed one by oneprocessed one by one
Batching reduces network round-tripsBatching reduces network round-trips
DataAdapter.UpdateBatchSize = DataAdapter.UpdateBatchSize = batch_sizebatch_size
Works inside transactionsWorks inside transactions
Works with SQL Server 7.0, 2000, Works with SQL Server 7.0, 2000, 20052005
Also available for OracleClient classesAlso available for OracleClient classes
Stand-alone DataTable Stand-alone DataTable
Batched Updates featureBatched Updates feature
XML Data Types in a XML Data Types in a DataSetDataSet
The DataTable accepts columns of The DataTable accepts columns of data-type 'xml'data-type 'xml'
type is System.Data.SqlTypes.SqlXml type is System.Data.SqlTypes.SqlXml defaults to a String unless defaults to a String unless DataAdapter.DataAdapter.UseProviderSpecificType = trueUseProviderSpecificType = true
exposed as an XPathDocument instanceexposed as an XPathDocument instance
can also be accessed via an XmlReadercan also be accessed via an XmlReader
makes it easier to work with XML as a makes it easier to work with XML as a document rather than a rowset of valuesdocument rather than a rowset of values
maintains fidelity of the XML contentmaintains fidelity of the XML content
User-Defined Types in a User-Defined Types in a DataSetDataSet
Populate DataSet with SQL or Stored Populate DataSet with SQL or Stored ProcedureProcedure
Update with SQL Statement or Stored Update with SQL Statement or Stored ProcedureProcedure
create the Command and Parameterscreate the Command and Parametersparam = da.UpdateCommand.Parameters.Add param = da.UpdateCommand.Parameters.Add
("@("@namename",SqlDbType.Udt)",SqlDbType.Udt)
param.UdtTypeName = "param.UdtTypeName = "type-nametype-name""
param.SourceColumn = "param.SourceColumn = "column-namecolumn-name""
or can use a SqlCommandBuilderor can use a SqlCommandBuilderuse timestamp column for conflict resolutionuse timestamp column for conflict resolution
otherwise UDT conflicts will not be detectedotherwise UDT conflicts will not be detected
AgendaAgenda
Enhancements to the DataSet classEnhancements to the DataSet class
SqlClient EnhancementsSqlClient EnhancementsAsynchronous CommandsAsynchronous Commands
SQL Cache DependencySQL Cache Dependency
SQL Server 2005 IntegrationSQL Server 2005 IntegrationMultiple Active Result SetsMultiple Active Result Sets
Generic Data StructuresGeneric Data StructuresList<T>List<T>
DictionaryDictionary
Asynchronous CommandsAsynchronous Commands
Ideal for multiple database queriesIdeal for multiple database queriesUsual Usual BeginBeginxxxxxx and and EndEndxxxxxx model modelSupports Polling, Wait and Callback Supports Polling, Wait and Callback modelsmodelsCatching asynchronous execution Catching asynchronous execution errorserrorsShould not generally be used with Should not generally be used with MARSMARS
use a separate connection for each use a separate connection for each CommandCommand
Add "async=true" to connection Add "async=true" to connection stringstring
Asynchronous Polling Asynchronous Polling ModelModel
Start asynchronous command Start asynchronous command execution:execution:IAsyncResult result = IAsyncResult result =
MyCommand.BeginExecuteReader()MyCommand.BeginExecuteReader()
Wait until execution is complete:Wait until execution is complete:while (! result.IsCompleted) {while (! result.IsCompleted) {
// execute other code here// execute other code here
}}
Fetch results:Fetch results:SqlDataReader reader = SqlDataReader reader =
MyCommand.EndExecuteReader(result )MyCommand.EndExecuteReader(result )
Asynchronous Wait (All) Asynchronous Wait (All) ModelModel
Start one or more asynchronous Start one or more asynchronous commands:commands:IAsyncResult resultIAsyncResult resultxx = =
MyCommand.BeginExecuteReader()MyCommand.BeginExecuteReader()
Wait for all commands to complete:Wait for all commands to complete: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)
Fetch results:Fetch results:SqlDataReader reader = SqlDataReader reader =
MyCommand.EndExecuteReader(resultMyCommand.EndExecuteReader(resultxx))
Ideal for ASP.NET Web applicationsIdeal for ASP.NET Web applications
Asynchronous Wait (Any) Asynchronous Wait (Any) ModelModel
Start one or more asynchronous Start one or more asynchronous commands as an array of commands as an array of IAsyncResult instances:IAsyncResult instances:IAsyncResult resultIAsyncResult resultxx = =
MyCommand.BeginExecuteReader()MyCommand.BeginExecuteReader()
Wait for each command to complete:Wait for each command to complete:for(int i=0; i < result_array.Length, i++) {for(int i=0; i < result_array.Length, i++) {
index = WaitHandle.WaitAny(result_array,index = WaitHandle.WaitAny(result_array,
timeout, true);timeout, true);
switch(index) {switch(index) {
case 0: SqlDataReader reader =case 0: SqlDataReader reader =
MyCommand.EndExecuteReader(resultMyCommand.EndExecuteReader(resultxx););
...etc......etc...
Asynchronous Callback Asynchronous Callback ModelModel
Start execution, specifying callback Start execution, specifying callback and passing command as the and passing command as the AsyncState:AsyncState:MyCommand.BeginExecuteReader(new MyCommand.BeginExecuteReader(new
AsyncCallback(MyCallback), cmd)AsyncCallback(MyCallback), cmd)
Provide a callback handler:Provide a callback handler:void MyCallback(IAsyncResult result) {void MyCallback(IAsyncResult result) {
SqlCommand cmd =SqlCommand cmd =
(SqlCommand) result.AsyncState;(SqlCommand) result.AsyncState;
SqlDataReader reader =SqlDataReader reader =
cmd.EndExecuteReader(result);cmd.EndExecuteReader(result);
}}
Catching Timeouts and Catching Timeouts and ErrorsErrors
For the WaitOne and WaitAll For the WaitOne and WaitAll methods:methods:
use try/catch around each "End" methoduse try/catch around each "End" method
For the WaitAny method:For the WaitAny method:
return value is equal to timeout valuereturn value is equal to timeout value
When using the Callback model:When using the Callback model:
use try/catch around "End" methoduse try/catch around "End" method
Asynchronous CommandsAsynchronous Commands
Execution ModelsExecution Models
AgendaAgenda
Enhancements to the DataSet classEnhancements to the DataSet class
SqlClient EnhancementsSqlClient EnhancementsAsynchronous CommandsAsynchronous Commands
SQL Cache DependencySQL Cache Dependency
SQL Server 2005 IntegrationSQL Server 2005 IntegrationMultiple Active Result SetsMultiple Active Result Sets
Notifications & Notifications & SqlDependencySqlDependency
Cache the data and then be notified Cache the data and then be notified when ANYTHING happens that would when ANYTHING happens that would give a different result if the query give a different result if the query was re-executedwas re-executed
Uses SQL Server 2005 Query Uses SQL Server 2005 Query NotificationsNotifications
bind SqlDependency to Command and bind SqlDependency to Command and execute itexecute it
fully integrated with ASP.NET as wellfully integrated with ASP.NET as well
Notifications Service for SQL 2000Notifications Service for SQL 2000Query Notifications add-in availableQuery Notifications add-in available
Creating a Creating a SqlDependencySqlDependency
Bind a SqlDependency to Command:Bind a SqlDependency to Command: SqlDependency dependency = new SqlDependency(cmd);SqlDependency dependency = new SqlDependency(cmd);
Specify the Callback Handler:Specify the Callback Handler: dep.OnChanged += new dep.OnChanged += new
OnChangedEventHandler(DataChanged);OnChangedEventHandler(DataChanged);
Add Callback Handler to project:Add Callback Handler to project: static void DataChanged(Object sender, static void DataChanged(Object sender,
SqlNotificationEventArgs args)SqlNotificationEventArgs args)
{ { // display details of the event// display details of the event
// refresh the data that was displayed last// refresh the data that was displayed last } }
Execute the Command:Execute the Command: reader = cmd.ExecuteReader();reader = cmd.ExecuteReader();
AgendaAgenda
Enhancements to the DataSet classEnhancements to the DataSet class
SqlClient EnhancementsSqlClient EnhancementsAsynchronous CommandsAsynchronous Commands
SQL Cache DependencySQL Cache Dependency
SQL Server 2005 IntegrationSQL Server 2005 IntegrationMultiple Active Result SetsMultiple Active Result Sets
Generic Data StructuresGeneric Data StructuresList<T>List<T>
DictionaryDictionary
Multiple Active Results Multiple Active Results SetsSets
Perform other database operations Perform other database operations while a SqlDataReader is open on the while a SqlDataReader is open on the connectionconnection
execute another query to get execute another query to get another DataReader/XmlReaderanother DataReader/XmlReader
execute DML statementsexecute DML statements
Multiple results sets can be activeMultiple results sets can be activeinterleave fetches to each Readerinterleave fetches to each Reader
interleave queries that do not return a interleave queries that do not return a result setresult set
Interleaving Results SetsInterleaving Results SetsTypical scenario:Typical scenario:
get a list of customers and iterate get a list of customers and iterate through themthrough them
for each customer, get a list of ordersfor each customer, get a list of orders
for each order, get a list of order linesfor each order, get a list of order lines
Previously this would require multiple Previously this would require multiple connectionsconnections
With MARS, use only one connectionWith MARS, use only one connectionproviding data is in the same databaseproviding data is in the same database
requires SQL Server 2005 or MDAC9requires SQL Server 2005 or MDAC9
Interleaved Results Sets Interleaved Results Sets ExampleExampleDataReader parentReader = Command1.ExecuteReader();DataReader parentReader = 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"];
DataReader childReader DataReader childReader
= Command2.ExecuteReader();= Command2.ExecuteReader();
// process child rows here// process child rows here
childReader.Close();childReader.Close();
}}
parentReader.Close();parentReader.Close();
Multiple Active Result SetsMultiple Active Result Sets
AgendaAgenda
Enhancements to the DataSet classEnhancements to the DataSet class
SqlClient EnhancementsSqlClient EnhancementsAsynchronous CommandsAsynchronous Commands
SQL Cache DependencySQL Cache Dependency
SQL Server 2005 IntegrationSQL Server 2005 IntegrationMultiple Active Result SetsMultiple Active Result Sets
Generic Data StructuresGeneric Data Structures
List<T>List<T>
DictionaryDictionary
Generics - List<T>Generics - List<T>
Self Re-dimensioning arraySelf Re-dimensioning array
Similar to ArrayList but betterSimilar to ArrayList but betterType-safe == fasterType-safe == faster
Easy to castEasy to castList<string> employees = new List<string>
employees.Add(“Joe”);employees.Add(“Jane”);
string[] developers = employees.ToArray();
Generics – Dictionary<T, Generics – Dictionary<T, F>F>
A type-safe HashtableA type-safe Hashtable
Add, Remove, and Search are Add, Remove, and Search are Constant time: Constant time: OO(1)(1)
Different Collision resolutionDifferent Collision resolution
© 2005 Microsoft Corporation. All rights reserved.This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.