ADO.NET and the .NET Framework v1.1
Of the thousands of classes Microsoft shipped in the .NET Framework, the subset of classes referred to collectively as ADO.NET (and organized in the System.Data namespace) is perhaps the most important for corporate developers. This is the case because data is always central to developing business software. I've also seen it firsthand when speaking on ADO.NET at TechEd and to .NET user groups around the country this past year.
As a result, it shouldn't be surprising that as Microsoft is readying to release the .NET Framework v1.1 and Visual Studio .NET 2003 (referred to as the "Everett" release), developers are keenly interested in the differences in ADO.NET between the two versions. In this article, I'll explore the most significant differences (as of the current beta release) and their implications and also leave you with a few ideas for what might be coming in ADO.NET in releases subsequent to Everett. If you're unfamiliar with ADO.NET, well, you're in luck. My book (published earlier this year), Teach Yourself ADO.NET in 21 Days, will take you through the System.Data namespace from start to finish.
Before getting into the details of the changes, however, I want to allay any fears. The majority of differences in behavior and functionality are fixes and will not break existing code. The rest are enhancements or additions that you can take advantage of to create better applications.
Additions to the Programming Model
Let's start by discussing four additions to the programming model.
New .NET Data Providers. VS .NET 2002 shipped with two .NET Data Providers: the SqlClient provider (found in the System.Data.SqlClient namespace) for accessing SQL Server 7.0 and 2000, and OleDb (found in the System.Data.OleDb namespace) for accessing data stores through OLE DB providers. The former is referred to as a narrow provider because it can be used to access only one data store, whereas the latter is a broad provider because it can be used with multiple data stores. Soon after the release of VS .NET 2002, Microsoft made available an ODBC .NET Data Provider on its MSDN web site. Later, it also posted an Oracle .NET Data Provider. Both of these providers will be included in the release of VS .NET 2003. The only caveat is that they will be moved under the System.Data namespace. For example, the ODBC provider available on MSDN organizes its classes in the Microsoft.Odbc namespace, whereas they will be placed in the System.Data.Odbc namespace in the Everett release. The Oracle .NET Data Provider will be in the System.Data.OracleClient namespace. The result is that VS .NET 2003 will contain two narrow providers for SQL Server and Oracle and two broad providers for ODBC and OLE DB.
HasRows. .NET Data Providers include data readers that implement the IDataReader interfacefor example, the SqlDataReader class in the SqlClient namespace. These data readers provide read-only, forward-only, cursor-style access to data (as opposed to the disconnected data access available with data adapters) by calling the ExecuteReader method of a command object and then iterating the data reader by calling its Read method. In the VS .NET 2002 release, the only way to determine whether the data reader returned rows was to check the result of the Read method for Nothing (null in C#). However, this was sometimes problematic because calling Read also positions the data reader on the first row, which might cause developers to inadvertently skip the first row if they were'nt careful. To avoid this situation, the data readers (SqlDataReader, OleDbDataReader, and OdbcDataReader) now include a HasRows method that can be interrogated after the ExecuteReader method is invoked. HasRows returns True if there are rows that can be accessed using the Read method.
EnlistDistributedTransaction. Although it probably won't often be used, the SqlConnection, OleDbConnection, and OdbcConnection objects now support the EnlistDistributedTransaction method. This method allows the connection to explicitly enlist in a distributed transaction managed by the Distributed Transaction Coordinator (DTC). To do so, however, you need to pass the transaction to enlist to using the Transaction property of the System.EnterpriseServices.ContextUtil class. Typically, you would simply rely on the .NET Data Provider to enlist in the transaction implicitly.
New Exception Types. The SqlClient provider now includes three new exception types, including SqlNullValueException, SqlTruncateException, and SqlTypeException (the base class from which the other two derive). These are now thrown in specific scenarios rather than the more generic SqlException. For example, when binding a numeric value to a SqlParameter, the value may have greater precision than the definition of the parameter. In v1.0, the data would simply be truncatedperhaps causing invalid data to be written to the database. In v1.0, a SqlTruncateException is thrown instead.