what’s new in system.data. agenda the common programming model the schema discovery api...
TRANSCRIPT
What’s New in System.DataWhat’s New in System.Data
AgendaAgenda
The Common Programming Model The Schema Discovery API Enhancements to the DataSet classSQL Server-specific enhancements
ADO.NET 2.0 goalsADO.NET 2.0 goals
ADO.NET 2.0 evolves without revolutions
People like ADO.NET the way it is :)Just upgrade; your code will work
Changes for performance & scalabilityDataSet and DataTable enhanced
Provider-independent APIIntegration with SQL Server 2005
Common programming model
Common programming model
Factory Class HierarchyFactory Class Hierarchy
IDb* interfaces (e.g. IDbConnection)IDb* interfaces (e.g. IDbConnection)
Db* abstract base classes (e.g. DbConnection)Db* abstract base classes (e.g. DbConnection)
Db*Base implementation classesDb*Base implementation classes
SqlSql OleDbOleDb ODBCODBC OracleOracle 33rdrd Party 1Party 1
33rdrd Party 2Party 2
Provider-Independent apps code to this layer
Provider-specific apps code to this layer
Common Provider ClassesCommon Provider Classes
In System.Data.Common namespace:for example:
DbCommand DbCommandBuilder DbConnection
DataAdapter DbDataAdapter DbDataReader
DbParameter DbParameterCollection DbTransaction
DbProviderFactory DbProviderFactories DbException
Using a Provider FactoryUsing a Provider FactoryImport the Required Namespace:using System.Data.Common
Create the Factory Instance:static DbProviderFactory factory = DbProviderFactories.GetFactory("provider-name")
Create Required Object Instances:DbConnection con = factory.CreateConnection()
DbCommand cmd = con.CreateCommand()
Provider EnumerationProvider EnumerationEach provider has an invariant name
for example: "System.Data.SqlClient", "System.Data.OracleClient"
Get a List of Installed Provider FactoriesDataTable dt = DbProviderFactories.GetFactoryClasses()
DbProviderFactory factory = DbProviderFactories.GetFactory(dt.Rows[x])
... or ...DbProviderFactory factory = DbProviderFactories.GetFactory( dt.Select("InvariantName='System.Data.SqlClient'") [0]["InvariantName"].ToString());
When Should I Use It?When Should I Use It?An OPTION only
Designed for tool and IDE suppliersConnection string details depends on database typeParameter names depend on provider type
PerformanceNo layer of overheadCreate factory once and reuseOtherwise equal Performance
the base class is returned from factory object
Schema Discovery APISchema Discovery API
Schema Discovery APISchema Discovery API
Get a List of Schemas:DataTable dt = conn.GetSchema("MetaDataCollections")
Get a Specific Schema:DataTable dt = conn.GetSchema("collection-name")
Get Selected Details from a Schema:DataTable dt = conn.GetSchema("collection-name",
restriction-array)
Schema SelectionSchema Selection
CollectionName Restrictions
CollectionName Restrictions
MetaDataCollections n/a Views 3
DataSourceInformation
n/a ViewColumns 4
DataTypes n/a Parameters 4
Restrictions n/a Procedures 4
ReservedWords n/a ProcedureColumns 4
Users 1 ForeignKeys 4
Databases 1 IndexColumns 5
Tables 4 Indexes 4
Columns 4 UserDefinedTypes 1
GetSchema("GetSchema("collection-namecollection-name",", restrictions[restrictions[xx])])
Some Metadata CollectionsSome Metadata Collections
Columns schema metadata collection
table_catalog table_schema table_name
column_name ordinal_position column_default
is_nullable data_type character_maximum_length
character_octet_length
numeric_precision numeric_precision_radix
numeric_scale datetime_precision character_set_catalog
character_set_schema character_set_name collation_catalog
Tables schema metadata collection
table_catalog table_schema table_name table_type
= restriction that can be used for selecting items
DataSet enhancementsDataSet enhancements
DataSet Serialization in .NET 1.1
DataSets serialize through DiffGram scripts
DataSetISerializable
Formatter
XML
SoapFormatter:BinaryFormatter:CompactFormatter
http://www.freewebs.com/compactFormatter/downloads.html
DataSet Serialization in .NET 2.0DataSet Serialization in .NET 2.0Binary Serialization of Contents
V 1.x DataSet always serialized to XMLgood for data interchange, bad for performance
Binary serialization an option in V 2.0fast and compact, especially as row counts increasejust set: DataSet.RemotingFormat = SerializationFormat.Binary
Internal Indexing of RowsInserts and deletes are log-nUpdates almost constant
Binary vs XML SerializationBinary vs 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 DataSetDataAdapter enhancements
DataAdapter.FillLoadOption and AcceptChangesDuringUpdate properties
DataSet.Load methodLoad(DataReader [, load-option] [, tables-array])optionally can use FillErrorEventHandler event to trap errors
The LoadOption EnumerationThe LoadOption Enumeration
Used by Load and Merge methodswhat happens when loading a row with same key
ds.Merge(loadoption, preservechanges)use preservechanges=True for overwriting original values but not current values
the LoadOption enumeration helps to support other scenarios
e.g. merging data from a different DB or from file
The LoadOption enumerationThe LoadOption enumeration
PreserveCurrentValues (default)overwrites original values, keeps current valuesgood to resync with original DB after a conflict
UpdateCurrentValuesoverwrites current values, keeps original onesgood to read data from DB without losing original data loaded in the dataset
OverwriteRowoverwrites both values, sets the row as unchanged
The LoadOption EnumerationThe LoadOption EnumerationRowState of
Existing RowPreserveCurrentValues (the default value)
UpdateCurrentValues OverwriteRow
Added Current = ExistingOriginal = IncomingRowState = Modified
Current = IncomingOriginal = ExistingRowState = Added
Current = IncomingOriginal = IncomingRowState = Unchanged
Modified Current = ExistingOriginal = IncomingRowState = Modified
Current = IncomingOriginal = ExistingRowState = Modified
Current = IncomingOriginal = IncomingRowState = Unchanged
Deleted Current = ExistingOriginal = IncomingRowState = Deleted
* Undo Delete Current = IncomingOriginal = ExistingRowState = Modified
* Undo Delete Current = IncomingOriginal = IncomingRowState = Unchanged
Unchanged Current = IncomingOriginal = IncomingRowState = Unchanged
Current = IncomingOriginal = Existing* if new value = existing value: RowState = Unchanged * else: RowState = Modified
Current = IncomingOriginal = IncomingRowState = Unchanged
No matching existing row in the table
Current = IncomingOriginal = IncomingRowState = Unchanged
Current = IncomingOriginal = ExistingRowState = Added
Current = IncomingOriginal = IncomingRowState = Unchanged
Stand-alone DataTable InstancesStand-alone DataTable InstancesCommon DataSet operations now also available on DataTable:
ReadXml, ReadXmlSchema, WriteXml, WriteXmlSchema, Clear, Clone, Copy, Merge
DataTable is now auto-serializable:
return a DataTable instance from a Web Service or via Remoting
Loading and Using a DataTableLoading and Using a DataTable
DataAdapter.Fill(DataTable)DataAdapter.Fill(DataTable[ ])
and more, including subsets of rows
DataAdapter.Update(DataTable)DataTable.Load(DataReader [, load-option] [, FillErrorEventHandler])
new methods: BeginLoadData, Load, EndLoadData
DataTable.GetDataReader methodstream data from a DataTable
1000 10000 100000 200000
Loaded Row s
Tim
e v1.x
v2.0
DataSet Load PerformanceDataSet Load Performance
3 times as fast for 100,000 rows - and even better with more!3 times as fast for 100,000 rows - and even better with more!
Using LoadDataRow APIUsing LoadDataRow API
More New FeaturesMore New FeaturesRowState values are now updateable
New methods: DataRow.SetAdded and DataRow.SetModifieduse Delete and AcceptChanges/RejectChanges for other states
DataTable.GetDataReader methodreturns a DataTableReaderyou can specify which tables to include
DataView.ToTable methodfiltering and sorting, can include only a subset of columnsdt = dv.ToTable(tableName, boolDistinct, columnNames())
Batched UpdatesBatched UpdatesDataSet updates are normally processed one by oneBatching reduces network round-trips
DataAdapter.UpdateBatchSize = batch_sizeWorks inside transactionsWorks with SQL Server 7.0, 2000, 2005
Also available for OracleClient classesMinor limitations
max 2000 parametersmaxrows = 2000 / paramsper rowoptimal numrows = 100-500 rows
XML Data Types in a DataSetXML Data Types in a DataSetThe DataTable accepts columns of
data-type 'xml'type is System.Data.SqlTypes.SqlXml
in Beta 2 defaults to a String unless DataAdapter.UseProviderSpecificType = true
exposed as an XPathDocument instancecan also be accessed via an XmlReadermakes it easier to work with XML as a document rather than a rowset of valuesmaintains fidelity of the XML content
User-Defined Types in a DataSetUser-Defined Types in a DataSetPopulate DataSet with SQL or Stored ProcedureUpdate with SQL Statement or Stored Procedure
create the Command and Parametersparam = da.UpdateCommand.Parameters.Add ("@name",SqlDbType.Udt)
param.UdtTypeName = "type-name"
param.SourceColumn = "column-name"
or can use a SqlCommandBuilderuse timestamp column for conflict resolutionotherwise UDT conflicts will not be detected
SqlClient enhancementsSqlClient enhancements
Asynchronous CommandsAsynchronous CommandsIdeal for multiple database queriesUsual Beginxxx and Endxxx modelSupports Polling, Wait and Callback modelsCatching asynchronous execution errorsShould not generally be used with MARS
use a separate connection for each Command
Add "async=true" to connection stringDoesn’t work on Win9x and ME clients
~ 3 secs
Application
Synchronous LatencySynchronous Latency
Rowset 1
Rowset 2
Rowset 3
Connection
Total time until all three displays filled:
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 secs
Application
Asynchronous ExecutionAsynchronous Execution
Rowset 1
Rowset 2
Rowset 3
Connection1
Connection2
Connection3
~ 8 secs Total time until all three displays filled:
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
Asynchronous Polling ModelAsynchronous Polling ModelStart asynchronous command execution:IAsyncResult result = MyCommand.BeginExecuteReader()
Wait until execution is complete:while (! result.IsCompleted) {
// execute other code here
}
Fetch results:SqlDataReader reader = MyCommand.EndExecuteReader(result )
Asynchronous Wait (All) ModelAsynchronous Wait (All) ModelStart one or more asynchronous
commands:IAsyncResult resultx = MyCommand.BeginExecuteReader()
Wait for all commands to complete:WaitHandle.WaitAll(new WaitHandle[] {result1.AsyncWaitHandle, result2.AsyncWaitHandle, result3.AsyncWaitHandle}, timeout-ms, true)
Fetch results:SqlDataReader reader = MyCommand.EndExecuteReader(resultx)
Ideal for ASP.NET Web applications
Asynchronous Wait (Any) ModelAsynchronous Wait (Any) ModelStart one or more asynchronous commands as an array of IAsyncResult instances:IAsyncResult resultx = MyCommand.BeginExecuteReader()
Wait for each command to complete:for(int i=0; i < result_array.Length, i++) {
index = WaitHandle.WaitAny(result_array,
timeout, true);
switch(index) {
case 0: SqlDataReader reader =
MyCommand.EndExecuteReader(resultx);
...etc...
Asynchronous Callback ModelAsynchronous Callback ModelStart execution, specifying callback
and passing command as the AsyncState:MyCommand.BeginExecuteReader(new AsyncCallback(MyCallback), cmd)
Provide a callback handler:void MyCallback(IAsyncResult result) {
SqlCommand cmd =
(SqlCommand) result.AsyncState;
SqlDataReader reader =
cmd.EndExecuteReader(result);
}
Catching Timeouts and ErrorsCatching Timeouts and Errors
For the WaitOne and WaitAll methods:use try/catch around each "End" method
For the WaitAny method:return value is equal to timeout value
When using the Callback model:use try/catch around "End" method
More SqlClient enhancementsMore SqlClient enhancements
Connection-level statisticsStatisticsEnabled propertyRetrieveStatistics method (return IDictionary)ResetStatistics method
AttachDbFileName in connection stringmust be absolute path in ADO.NET 1.xcan be a relative path in ADO.NET 2.0great to support SQL Server 2005 Express (MSDE)
Enhancements for SQL Server 2005Enhancements for SQL Server 2005
Multiple Active ResultSets (MARS)Multiple Active ResultSets (MARS)
Opening a second “cursorless” resultset on the same connection
ADO opens a new connection behind the scenesADO.NET 1.x throws an exception
Fully supported in ADO.NET 2.0 & SQL Server 2005
required changes in network librariescommands on same connection share the same transaction
SqlDependency classSqlDependency classADO.NET 2.0 SqlDependency class tracks dependencies on query resultsBuilt on SQL Server 2005 Query Notifications
or Notifications Service for SQL 2000Query Notifications add-in available
Wraps the low-level SqlNotificationRequest type
Doesn’t require an open connection
Don’t use with many clientsall would refresh data at the same time
SqlCommand cmd;cmd = new SqlCommand("SELECT * FROM Authors", conn);SqlDependency dep = new SqlDependency(cmd);dep.OnChanged += new OnChangedEventHandler(OnDepChanged);cmd.ExecuteReader();
ASP.NET Cache DependencyASP.NET Cache Dependency
SqlCacheDependency is ASP.NET-specific wrapper that work with SQL Server 7.0 and 2000 too
invalidates data in the Cache based on table (not query!) changes
Enable notifications for required tablesCreate triggers to handle incoming statementsCommand-line tool (aspnet_regsql) or methods of SqlCacheDependencyAdmin
// SELECT … WHERE country=‘USA’ trigger also for ‘UK’SqlCacheDependency dep;dep = new SqlCacheDependency(database, table);Cache.Insert("MyData", dataSet, dep);
Notifications & SqlDependencyNotifications & SqlDependencyCache the data and then be notified
when ANYTHING happens that would give a different result if the query was re-executedUses SQL Server 2005 Query Notifications
bind SqlDependency to Command and execute itfully integrated with ASP.NET as well
Notifications Service for SQL 2000Query Notifications add-in available
Support for new data typesSupport for new data types
ADO.NET 2.0 supports SQL Server 2005 XML native data type, user-defined types
SqlXml and SqlUdt in System.Data.SqlTypes
also supported by SqlParameter
DataReader returns UDTs and XML dataGetValue and GetString, respectively
the new SqlMetaData type can return extended properties
XML schema collection for XML typedatabase name of a UDT
The XML Data TypeThe XML Data Type
SQL Server 2005 provides an XML database and schema repository
XML data-typing and indexing are supported for XML columns
XML data type can be used in T-SQLwhen inserting and selecting data
when querying and updating data
Using the XML Data TypeUsing the XML Data Type
Accessing XML data from ADO.NETreading XML with a DataReader
updating XML with a SQL statement
XML Data Manipulation LanguageXML DML allows updates to the data within XML columns using T-SQL
functions include: modify(), insert(), delete(), replace(), column() and value()
XML DML QueriesXML DML QueriesMethods of the "xml" data type within SQL ServerQuery the data in an XML column to get individual values without retrieving all of itManipulate the data in an XML column without retrieving any of itExample:UPDATE table SET xml-column.modify('
replace value of (/root/element)[index]
with "new-value"')
WHERE column-name = criteria
Password changingPassword changing
SQL Server 2005 supports password expiration
requires Windows Server 2003
the ChangePassword method of the SqlConnection type
you shouldn’t hard-code the password in the connection string (a sound practice anyway)store in config file in encrypted format
What else?What else?
Promotable TransactionsPromotable TransactionsAutomatic promotion of local transactions into distributed ones
Uses TransactionContext
Fully integrated with the classes in System.Transactions namespace
Works with transactions started in SQL Server 2005 CLR code
Context flows even if you start in-proc
Don't promote single RM transactions
Auto-promoting a TransactionAuto-promoting a TransactionInitialize the transaction scope:TransactionScope scope = new TransactionScope (TransactionScopeOptions.RequiresNew);
Create a connection and do workDo *not* enrol - uses a local transaction
Create second connection and do worktransaction auto-promoted to distributed
Vote to commit or rollback:scope.Consistent = [true|false];
Dispose of transaction when complete:scope.Dispose();
TracingTracing
OLEDB lacks a standard trace modemakes it harder to solve OLEDB and ADO problems
ADO.NET 2.0 traces every API callsimilar to ODBC tracingall Microsoft providers are instrumentedopen standard for 3rd party provider writers
DataSet has built-in diagnostics too
Support for untrusted appsSupport for untrusted apps
in ADO.NET 1.1 only the SQL Server provider can be used in partially-trusted appsin ADO.NET 2.0 all four Microsoft providers are supported in this scenario
necessary for ClickOnce deployment
Must be enabled from .NET configuration panel
Other ADO.NET 2.0 enhancementsOther ADO.NET 2.0 enhancements
Doesn’t depend on MDACBetter error handling and clearer error messagesBetter control on connection pooling (SqlClient and OracleClient)
SqlConnection.ClearPool clears a specific poolSqlConnection.ClearPools clears all the pools in an appdomain
Even more for SQL Server 2005Even more for SQL Server 2005
Support for snapshot isolation levelTransparent support for client failover
when the a SQL Server instance fails and work is shifted to the backup (“witness”) instance
SummarySummaryUnderstood how to use the Common Programming Model to write provider-independent codeExplored the use of the Schema Discovery API to examine the schema and structure of databasesReviewed the enhancements to the DataSet class that provide better performance and increased usability
Microsoft®Microsoft®