Appendix A. What's New in ADO.NET Since Version 1.0

ADO.NET is a set of classes that gives .NET applications access to relational, XML, and application data. The classes let you connect to data sources such as SQL Server and Oracle, as well as to data sources exposed through OLE DB and ODBC, and XML data. After you connect to these data sources, the ADO.NET classes let you retrieve, manipulate, and update data.

This appendix describes the new functionality, support, and features in ADO.NET since version 1.0.

A.1. ADO.NET 2.0

ADO.NET 2.0 was released as part of the release of .NET Framework 2.0. This section provides an overview of both new features in ADO.NET 2.0 and of significant changes and enhancements in ADO.NET 2.0 since ADO.NET 1.0.

Data Provider Enumeration and Factories

Data providers in ADO.NET 1.0 and 1.1 are a set of provider-specific classes that implement generic interfaces. These interfaces can be used to write code that is data provider-independent. For example, the data connection classes in the Microsoft SQL Server data provider (SqlConnection) and the Microsoft Oracle data provider (OracleConnection) both implement the IDbConnection interface. Code based on the IDbConnection interface that is common to both classes, rather than a database-specific instance of a data provider, is independent of the data provider and therefore not dependent on the underlying database. The disadvantage of the interface approach is that you cannot use the interface to access any database-specific features implemented as members of the data provider class but not defined as part of the interface—the ChangeDatabase() method of the Oracle data provider, for example.

ADO.NET 2.0 introduces the Common Model, based on the Factory design pattern, which uses a single API to access databases having different providers. Data provider factories let your code work with multiple data providers without choosing a specific provider. The factory class creates and returns a strongly typed, provider-specific object based on information in the request. This lets you write data provider-independent code and select the provider at runtime. Using the Common Model, it becomes easier to write an application to support multiple databases.

The DbProviderFactories class in the System.Data.Common namespace lets you retrieve information about installed .NET data providers. The static GetFactoryClasses() method returns a DataTable object containing information about the installed data providers that implement the abstract base class DbProviderFactory, with the schema described in Table A-1.

Table A-1. DataTable schema for GetFactoryClasses( ) method results

Column name

Description

Name

Data provider name.

Description

Data provider description.

InvariantName

A unique identifier for a data provider registered in machine.config in the <system.data><DbProviderFactories> element. For example, the invariant name for SQL Server is System.Data.SqlClient.

The invariant name is used to programmatically refer to the data provider.

AssemblyQualifiedName

Fully qualified name of the data provider factory class—enough information to instantiate the object.

The following console application uses the DbProviderFactories class to get information about the installed data providers:

	using System;
	using System.Data;
	using System.Data.Common;

	class Program
	{
	    static void Main(string[] args)
	    {
	        DataTable dt = DbProviderFactories.GetFactoryClasses();
	        foreach (DataRow row in dt.Rows)
	        {
	            Console.WriteLine("{0}\n\r  {1}\n\r  {2}\n\r  {3}\n\r",
	                row["Name"], row["Description"], row["InvariantName"],
	                row["AssemblyQualifiedName"]);
	        }

	        Console.WriteLine("Press any key to continue.");
	        Console.ReadKey();
	    }
	}

The output is shown in Figure A-1.

Information about installed data providers

Figure A-1. Information about installed data providers

The providers listed in Figure A-1 correspond to the DbProviderFactories element in machine.config, shown in the following excerpt:

	<system.data>
	  <DbProviderFactories>
	    <add name="Odbc Data Provider" invariant="System.Data.Odbc"
	      description=".Net Framework Data Provider for Odbc"
	      type="System.Data.Odbc.OdbcFactory,
	      System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
	    />
	    <add name="OleDb Data Provider" invariant="System.Data.OleDb"
	      description=".Net Framework Data Provider for OleDb"
	      type="System.Data.OleDb.OleDbFactory,
	      System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
	    />
	    <add name="OracleClient Data Provider" invariant="System.Data.OracleClient"
	      description=".Net Framework Data Provider for Oracle"
	      type="System.Data.OracleClient.OracleClientFactory, System.Data.OracleClient,
	      Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
	    <add name="SqlClient Data Provider" invariant="System.Data.SqlClient"
	      description=".Net Framework Data Provider for SqlServer"
	      type="System.Data.SqlClient.SqlClientFactory, System.Data, Version=2.0.0.0,
	      Culture=neutral, PublicKeyToken=b77a5c561934e089" />
	    <add name="Microsoft SQL Server Compact Data Provider"
	      invariant="System.Data.SqlServerCe.3.5"
	      description=".NET Framework Data Provider for Microsoft SQL Server Compact"
	      type="System.Data.SqlServerCe.SqlCeProviderFactory,
	      System.Data.SqlServerCe, Version=3.5.0.0, Culture=neutral,
	      PublicKeyToken=89845dcd8080cc91" />
	   </DbProviderFactories>
	 </system.data>

The static GetFactory() method of the DbProviderFactories class takes a single argument—either a DataRow object from the table returned by the GetFactoryClasses() method or a string containing the invariant name of the provider—and returns a DbProviderFactory instance for that data provider.

The DbProviderFactory class is an abstract base class that every ADO.NET 2.0 data provider must implement. DbProviderFactory is a data provider-independent class that provides a strongly typed object based on information supplied at runtime. The provider-specific classes derived from DbProviderFactory installed with .NET Framework 2.0 are listed in Table A-2.

Table A-2. Provider-specific classes derived from DbProviderFactory installed with .NET Framework 2.0

Factory class

Description

System.Data.Odbc.OdbcFactory

Used to create instances of ODBC provider classes

System.Data.OleDb.OleDbFactory

Used to create instances of OLE DB provider classes

System.Data.OracleClient.OracleClientFactory

Used to create instances of Oracle provider classes

System.Data.SqlClient.SqlClientFactory

Used to create instances of SQL Server provider classes

The...