Design of the Data Access Application Block
This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This page may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.
|The latest Enterprise Library information can be found at the Enterprise Library site.|
The Data Access Application Block includes the following features:
- A simple and efficient way of working with different database systems (see Designing for Simplified Data Access)
- A way of developing database-agnostic applications (see Designing for Database-Agnostic Applications)
- An easy way to adjust and validate the database configuration settings
The application block was designed to achieve the following goals:
- Encapsulate the logic used to perform the most common data access tasks.
- Eliminate common coding errors, such as failing to close connections.
- Relieve developers of the need to write duplicated code for common data access tasks.
- Reduce the need for custom code.
- Incorporate best practices for data access, as described in the .NET Data Access Architecture Guide.
- Ensure that, as far as possible, the application block functions work with different types of databases.
- Ensure that applications written for one type of database are, in terms of data access, the same as applications written for another type of database.
Figure 1 illustrates the interrelationship between the key classes in the Data Access Application Block.
Design of the Data Access Application Block
Assuming that the client code is using the application block configuration information, and not using the Unity Application Block to create instances of objects, it calls the static CreateDatabase method on the DatabaseFactory class to create instances of the Database object. The DatabaseFactory class uses configuration information found in the configuration file to determine the specific Database object type to construct and return to the application. The factory uses the following criteria to determine the Database object type to construct:
- If the client code passes a database instance name that identifies a connection string in the configuration file, the factory uses that string to create the Database object.
Note: The .NET Framework classes maintain the connection strings in the connectionStrings section of the configuration file. This means that connection string definitions can be shared among all applications that access the connectionStrings section.
- If the client code does not pass a database instance name, the factory identifies the connection string by the default instance setting in the configuration file. The defaultDatabase attribute in the dataConfiguration configuration section controls the default instance. The following XML fragment from a configuration file shows a default instance that corresponds to the Production connection string.
The <connectionStrings> section in the configuration file maps logical identifiers (names) to connection strings and DbProviderFactory types. The DatabaseFactory object obtains the logical name of the ADO.NET data provider from the connection string. The DatabaseFactory object then calls the .NET Framework DbProviderFactory class to obtain the fully qualified type name for the ADO.NET data provider. The DatabaseFactory object uses this information to determine the type of Database object to construct. Although the .NET Framework considers database provider names in connection strings to be optional, the Data Access Application Block requires them.
The application block configuration code contains default mappings. These map a SqlDatabase object to a System.Data.SqlClient data provider, an OracleDatabase object to a System.Data.OracleClient data provider, and a GenericDatabase object to all other data providers. You can use the configuration tools to override the default mappings.
Changing the default mappings or using the configuration tools to add new mappings creates a providerMappings section in the configuration file. The providerMappings section maps the DbProviderFactory type to the Database type. You can add your own mapping by creating your own database class and mapping it a DbProviderFactory object.
The abstract base class Database defines the common interface and provides much of the implementation for the data access methods. The SqlDatabase class and OracleDatabase class derive from the Database class. They provide methods to their respective database server systems, which include common functionality that is implemented differently from database to database, as well as functionality unique to that database system. The application block also includes a GenericDatabase class. This class does not provide any database-specific features but operates with any ADO.NET data provider.
The application block supports the dynamic discovery of parameters for stored procedures. This discovery requires a round trip to the database system. The ParameterCache class allows parameter information to be cached, thus avoiding round trips for subsequent invocations of the same stored procedure. (The GenericDatabase class does not support parameter discovery).