Chapter 3 Introduction to ADO.NET. 3.1 The ADO and ADO.NET ActiveX Data Object (ADO) is developed based on Object Linking and Embedding (OLE) and Component Object Model (COM) technologies.
Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.
3.1 The ADO and ADO.NET
ActiveX Data Object (ADO) is developed based on Object Linking and Embedding (OLE) and Component Object Model (COM) technologies.
For recent decade, ADO has been the preferred interface for Visual Basic programmers to access various data sources, with ADO 2.7 being the latest version of this technology.
The development history of data accessing methods can be traced back to the mid-1990s with Data Access Object (DAO), and then followed by Remote Data Object (RDO), which was based on the Open Database Connectivity (ODBC). In the late 1990s, the ADO that is based on OLEDB is developed.
ADO.NET is a new version of ADO and it is based mainly on the Microsoft .NET Framework. The underlying technology applied in ADO.NET is very different from the COM-based ADO.
In this chapter, you will:
The classes provided by ADO.NET are core to develop a professional data-driven application and they can be divided into the following three major components:
These three components are located at the different namespaces. The DataSet and the DataTable classes are located at the System.Data namespace. The classes of the Data Provider are located at the different namespaces based on the types of the Data Providers.
Data Provider contains four classes: Connection, Command, DataAdapter and DataReader. These four classes can be used to perform the different functionalities to help you to:
The ADO.NET architecture can be divided into two logical pieces:
command execution and caching.
3.4.1 The Data Provider
The Data Provider can also be called a data driver and it can be used as a major component for your data-driven applications. The functionalities of the Data Provider, as its name means, are to:
The Data Provider is physically composed of a binary library file and this library is in the DLL file format. Sometimes this DLL file depends on other DLL files, so in fact a Data Provider can be made up of several DLL files. Based on the different kinds of databases, Data Provider can have several versions and each version is matched to each kind of database. The popular versions of the Data Provider are:
The different data providers are located at the different namespaces, and these namespaces hold the various data classes that you must import into your code in order to use those classes in your project.
Table 3-1 lists the most popular namespaces used by the different data providers and used by the DataSet and the DataTable.
The .NET Framework Data Provider for ODBC uses native ODBC Driver Manager (DM) through COM interlope to enable data access. The ODBC .NET data provider provides access to ODBC data sources with the help of native ODBC drivers in the same way that the OleDb .NET data provider accesses native OLE DB providers.
The ODBC.NET supports the following Data Providers:
The System.Data.OleDb namespace holds all classes used by the .NET Framework Data Provider for OLE DB. The .NET Framework Data Provider for OLE DB describes a collection of classes used to access an OLE DB data source in the managed space. The OLE DB.NET data access technique supports the following Data Providers:
This Data Provider provides access to a SQL Server version 7.0 or later database using its own internal protocol. The functionality of the data provider is designed to be similar to that of the .NET Framework data providers for OLE DB, ODBC, and Oracle. All classes related to this Data Provider are defined in a DLL file and is located at the System.Data.SqlClient namespace. Although Microsoft provides different Data Providers to access the data in SQL Server database, such as the ODBC and OLE DB, for the sake of optimal data operations, it is highly recommended to use this Data Provider to access the data in an SQL Server data source.
This Data Provider is an add-on component to the .NET Framework that provides access to the Oracle database. All classes related to this Data Provider are located in the System.Data.OracleClient namespace. This provider relies upon Oracle Client Interfaces provided by the Oracle Client Software. You need to install the Oracle Client software on your computer to use this Data Provider.
Microsoft provides multiple ways to access the data stored in an Oracle database, such as Microsoft ODBC for Oracle and OLE DB, you should use this Data Provider to access the data in an Oracle data source since this one provides the most efficient way to access the Oracle database.
Data Provider contains four sub-classes and the Connection component is one of them. This class provides a connection between your applications and the database you selected to connect to your project. To use this class to setup a connection between your application and the desired database, you need first to create an instance or an object based on this class.
The Connection object you want to use depends on the type of the data source you selected. Data Provider provides four different Connection classes and each one is matched to one different database.
Table 3-3 lists these popular Connection classes used for the different data sources:
The connection string is a property of the Connection class and it provides all necessary information to connect to your data source. Regularly this connection string contains a quite few parameters to define a connection, but only five of them are popularly utilized for most data-driven applications:
A typical data connection instance with a general connection string can be expressed by the following codes:
Connection = NewxxxConnection(“Provider = MyProvider;” & _
“Data Source = MyServer;” & _
“Database = MyDatabase;” & _
“User ID = MyUserID;” & _
“Password = MyPassWord;”)
where xxx should be replaced by the selected Data Provider in your real application, such as OleDb, Sql or Oracle. You need to use the real parameter values implemented in your applications to replace those nominal values such as MyServer, MyDatabase, MyUserID and MyPassWord in your application.
The Provider parameter indicates the database driver you selected. If you installed a local SQL server and client such as the SQL Server 2005 Express on your computer, the Provider should be localhost. If you are using a remote SQL Server instance, you need to use that remote server’s network name. If you are using the default named instance of SQLX on your computer, you need to use .\SQLEXPRESS as the value for your Provider parameter. For the Oracle server database, you do not need to use this parameter.
The Data Source parameter indicates the name of the network computer on which your SQL server or Oracle server is installed and running.
The Database parameter indicates your database name.
The User ID and Password parameters are used for the security issue for your database. In most cases, the default Windows NT Security Authentication is utilized.
Some typical Connection instances are listed below:
OLE DB Data Provider for Microsoft Access Database
Connection = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;"& _
"Data Source=C:\database\CSE_DEPT.mdb;"& _
"User ID=MyUserID;" & _
SQL Server Data Provider for SQL Server Database
Connection = New SqlConnection("Server=localhost;"+ _
"Data Source=Susan\SQLEXPRESS;"+ _
Oracle Data Provider for Oracle Database
Connection = New OracleConnection("Data Source=XE;"+ _
"User ID=system;"+ _
To create a real connection between your database and your applications, the Open() method of the Connection class is called and it is used to open a connection to a data source with the property settings specified by the connection string.
An example of opening an OLEDB connection is shown in Figure 3-3.
The Close() method is a partner of the Open() method and it is used to close a connection between your database and your applications when you finished your data operations to the data source. You should close any connection object you connected to your data source after you finished the data access to that data source, otherwise a possible error may be encountered when you try re-open that connection in the next time as you run your project.
Unlike the Open() method, which is a key to your data access and operation to your data source, the Close() method does not throw any exceptions when you try to close a connection that has already been closed. So you do not need to use a Try….Catch block to catch any error for this method.
The Dispose() method of the Connection class is an overloaded method and it is used to releases the resources used by the Connection object. You need to call this method after the Close() method is executed to perform a cleanup job to release all resources used by the Connection object during your data access and operations to your data source.
After the Close() and Dispose() methods executed, you can release your reference to the Connection instance by setting it to Nothing. A piece of example code is shown in Figure 3-4.
Command objects are used to execute commands against your database such as a data query, an action query, and even a stored procedure. In fact, all data accesses and data operations between your data source and your applications are achieved by executing the Command object with a set of parameters.
Commandclass can be divided into the different categories and these categories are based on the different Data Providers. For the popular Data Providers, such as OLE DB, ODBC, SQL Server and Oracle, each one has its own Command class. Each Command class is identified by the different prefix such as OleDbCommand, OdbcCommand, SqlCommand and OracleCommand. Although these different Command objects belong to the different Data Providers, they have the similar properties and methods, and they are equivalent in functionalities.
Depends on the architecture of the ADO.NET, the Command object can have two different roles. Refer to Figures 3-1 and 3-2 in this chapter. In Figure 3-1, if a TableAdapter is utilized to perform a data query and all data tables are embedded into the DataSet as a data catching unit, the Command object is embedded into the different data query method of the TableAdapter, such as SelectCommand, InsertCommand, UpdateCommand and DeleteCommand and is executed based on the associated query type. In this case, the Command object can be executed indirectly, which means that you do not need to use any Executing method to run the Command object directly, instead you can run it by executing the associated method of the TableAdapter.
In Figure 3-2, each data table can be considered as an individual table. The Command object can be executed directly based on the attached parameter collection that is created and initialized by the user.
The Command class contains more than 10 properties, but only four of them are used popularly in most applications:
ParamName, sqlDbType, intSize)126.96.36.199The Constructors and Properties of the Parameter Class
The Parameter class has four popular constructors, which are shown in Figure 3-5 (an SQL Server Data Provider is used as an example).
When you add a Parameter object to the Parameters collection of a Command object, the Command object needs to know the relationship between that added parameter and the parameters you used in your SQL query string. Different parameter mappings are used for different Data Providers. Table 3-5 lists these mappings.
Both OLE DB and ODBC Data Providers used a so-called Positional Parameter Mapping, which means that the relationship between the parameters defined in an SQL statement and the added parameters into a Parameters collection is one-to-one in the order. In other words, the order in which the parameters appear in an SQL statement and the order in which the parameters are added into the Parameters collection should be exactly identical. The Positional Parameter Mapping is indicated with a question mark ?.
Both SQL Server and Oracle Data Provider used the Named Parameter Mapping, which means that each parameter, either defined in an SQL statement or added into a Parameters collection, is identified by the name. In other words, the name of the parameter appeared in an SQL statement or a stored procedure must be identical with the name of the parameter you added into a Parameters collection.
To add Parameter objects to an Parameters collection of a Command object, two popular ways are generally adopted, Add() method and AddWithValue() method.
The Add() method is an overloaded method and it has five different protocols, but only two of them are widely used. The protocols of these two methods are shown below.
ParameterCollection.Add( value As SqlParameter ) As SqlParameter
ParameterCollection.Add( paramName As String, Value As Object )
The AddWithValue() method is similar to the second Add() method with the following protocol:
ParameterCollection.AddWithValue( paramName As String, Value As Object )
The constructor of the Command class is an overloaded method and it has multiple protocols. Four popular protocols are listed in Figure 3-8 (an SQL Server Data Provider is used as an example).
The actual execution of a Command object is to run one of methods of the Command class to perform the associated data queries or data actions. Four popular methods are widely utilized for most data-driven applications and Table 3-6 lists these methods.
The DataAdapter serves as a bridge between a DataSet and a data source for retrieving and saving data. The DataAdapter provides this bridge by mapping Fill, which changes the data in the DataSet to match the data in the data source, and Update, which changes the data in the data source to match the data in the DataSet.
The DataAdapter connects to your database using a Connection object and it uses Command objects to retrieve data from the database and populate those data to the DataSet and related classes such as DataTables, also the DataAdapter uses Command objects to send data from your DataSet to your database.
To perform data query from your database to the DataSet, the DataAdapter uses the suitable Command objects and assign them to the appropriate DataAdapter properties such as SelectCommand, and execute that Command. To perform other data manipulations, the DataAdapter uses the same Command objects but assign them with different properties such as InsertCommand, UpdateCommand and DeleteCommand to complete the associated data operations.
The DataAdapter is a Data Provider-dependent component. This means that the DataAdapter has different versions based on the used Data Provider.
The DataAdapter has more than 10 methods available. Table 3-9 lists some most often used methods.
Among these methods, the Dispose, Fill, FillSchema and Update are most often used methods.
The DataReader class is a read-only class and it can only be used to retrieve and hold the data rows returned from a database executing an ExecuteReader method. This class provides a way of reading a forward-only stream of rows from a database. Depends on the Data Provider you are using, four popular DataReaders are provided by four Data Providers. They are OdbcDataReader, OleDbDataReader, SqlDataReader and OracleDataReader.
To create a DataReader instance, you must call the ExecuteReader method of the Command object, instead of directly using a constructor since the DataReader class does not have any public constructor.
Table 3-11 lists most public properties of the SqlDataReader class. All other DataReader classes have the similar properties.
The DataReader class has more than 50 public methods. Table 3-12 lists the most useful methods of the SqlDataReader class. All other DataReader classes have the similar methods.
The DataSet, which is an in-memory cache of data retrieved from a database, is a major component of the ADO.NET architecture. The DataSet consists of a collection of DataTable objects that you can relate to each other with DataRelation objects. In other words, a DataSet object can be considered as a table-container that contains a set of data tables with the DataRelation as a bridge to relate all tables together.
The definition of the DataSet class is a generic idea, which means that it is not tied to any specific type of database. Data can be loaded into a DataSet by using a TableAdapter from many different databases such as Microsoft Access, Microsoft SQL Server, Oracle, Microsoft Exchange, Microsoft Active Directory, or any OLE DB or ODBC compliant database.
Although not tied to any specific database, the DataSet class is designed to contain relational tabular data as one would find in a relational database.
Figure 3-15 shows a global relationship between the DataSet object, other data objects and the Visual Basic 2005 application.
DataTable class can be considered as a container that holds the Rows and Columns collections, and the Rows and Columns collections contain a set of rows (or DataRow objects) and a set of columns (or DataColumn objects) from a data table in a database.
The DataTable is a directly mapping to a real data table in a database or a data source and it store its data in a mapping area, or a block of memory space that is associated to a data table in a database as your project runs.
The DataTable class is located in the System.Data namespace and it is a Data Provider independent component, which means that only one set of DataTable objects are existed no matter what kind of Data Provider you are using in your applications.
When accessing DataTable objects, note that they are conditionally case sensitive. For example, if one DataTable is named "faculty" and another is named "Faculty", a string used to search for one of the tables is regarded as case sensitive. However, if "faculty" exists and "Faculty" does not, the search string is regarded as case insensitive. A DataSet can contain two DataTable objects that have the same TableName property value but different Namespace property values.
If you are creating a DataTable programmatically, you must first define its schema by adding DataColumn objects to the DataColumnCollection (accessed through the Columns property). To add rows to a DataTable, you must first use the NewRow method to return a new DataRow object.
The DataTable has four overloaded constructors and Table 3-18 lists three most often used constructors.
The main topic of this chapter is an introduction to the ADO.NET, which includes the architectures, organizations and components of the ADO.NET.
Fundamentally the ADO.NET is a class container and it contains three basic components: Data Provider, DataSet and DataTable. Furthermore, the Data Provider contains four sub-components: Connection, Command, TableAdapter and DataReader.
All four sub-components of the Data Provider are called Data Provider-dependent components. The popular versions of the Data Provider are:
OLE DB Data Provider
ODBC Data Provider
Microsoft SQL Server Data Provider
Oracle Data Provider
By finishing this chapter, you should be able to: