本篇讲述如何在应用中使用数据访问模块。首先,讲述如何配置模块并且和应用整合;其次是,如何使用数据访问模块完成常用的功能,例如,获取单条数据,或者是使用DataSet返回多条数据;最后,讲述一些关系连接管理、参数处理、异常处理的主题。
主要包括下面的主题:
- 配置模块
- 在应用中添加代码
- 创建Database对象
- 创建DbCommand对象
- 管理连接
- 使用TransactionScope类
- 创建分布式的数据库应用
- 异常处理
- 参数处理
1、配置模块
默认情况下,配置信息是不加密的,里面的用户名和密码等敏感信息是明文的。虽然config文件从外界是访问不到的,但是还是要做好加密工作。可以对文件进行加密,或者是配置节加密,以及读写的权限控制。
2、配置信息的的结构
<
configSections
>
<
section
name
="dataConfiguration"
type
="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
/>
<
section
name
="oracleConnectionSettings"
type
="Microsoft.Practices.EnterpriseLibrary.Data.Oracle.Configuration.OracleConnectionSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
/>
</
configSections
>
3、添加应用代码
数据访问模块支持访问数据库的常用方案。
首先要做一些准备工作,然后就是创建Database对象,调用适当的方法来完成所需功能。
准备工作:
1)添加模块的程序集引用。添加对程序集Microsoft.Practices.EnterpriseLibrary.Data.dll的引用。
2)添加对程序集Microsoft.Practices.EnterpriseLibrary.Common.dll和Microsoft.Practices.ObjectBuilder2.dll的引用。
3)在代码文件中添加命名空间:
using Microsoft.Practices.EnterpriseLibrary.Data;
using System.Data;
4、创建Database对象
所有的数据访问方法都是通过Database对象执行的,你可以使用DatabaseFactory类创建Database对象。工厂创建的具体的Database类型决定于应用的配置信息。另外你可以使用Unity创建数据访问模块的对象。
你可以使用配置工具制定默认的Database实例,当DatabaseFactory调用没有参数的CreateDatabase方法的时候就会创建默认的Database实例。下面的代码是没有使用Unity的情况下创建Database对象。
Database db
=
DatabaseFactory.CreateDatabase();
也可以指定名称来创建Database对象,例如:
Database db
=
DatabaseFactory.CreateDatabase(
"
Sales
"
);
你也可以通过连接字符串创建指定类型的Database对象。在下面的代码中,假定GetConnectionString方法可以获取一个Sql Server的连接字符串,就可以用SqlDatabase类的构造函数创建SqlDatabase对象。
//
Assume the method GetConnectionString exists in your application and
//
returns a valid connection string.
string myConnectionString = GetConnectionString();
SqlDatabase sqlDatabase = new SqlDatabase(myConnectionString);
5、创建DbCommand对象
创建DbCommand对象的方法分类两类:
- 一类是代表存储过程调用的DbCommand对象
- 一类是代表SQL语句的DbCommand对象
为存储过程创建DbCommand的方法还提供了参数缓存。
创建DbCommand对象的方法都在Database类上,包括:
- GetStoredProcCommand,为存储过程创建一个DbCommand对象
Database db = DatabaseFactory.CreateDatabase();
DbCommand cmd = db.GetStoredProcCommand("GetProductsByCategory");
- GetSqlStringCommand,为SQL语句创建一个DbCommand对象
Database db
=
DatabaseFactory.CreateDatabase();
string
sql
=
"
Select CustomerID, LastName, FirstName From Customers
"
;
DbCommand cmd
=
db.GetSqlStringCommand(sql);
6、连接管理
数据库连接是有限的资源,对于可扩展的应用来说,正确的管理他们是必要的。只在需要的时候保持连接打开、不需要时候关闭他们是一个很好的实践。Database类的大部分方法在每次调用数据库的时候都需要处理打开和关闭数据库。应用中不需要包含这方面的处理代码。默认情况下,由于性能原因,当你使用close方法的时候,ADO.NET会将连接返回给连接池,而不是关闭它们。因此,你不需要缓存Database对象。
例如,执行ExecuteDataSet方法返回一个包含数据的DataSet对象。将返回一个本地的拷贝,ExecuteDataSet方法将会打开一个连接,加载数据到DataSet,然后再返回结果之前关闭链结。
Database db
=
DatabaseFactory.CreateDatabase();
string
sql
=
"
Select ProductID, ProductName From Products
"
;
DbCommand cmd
=
db.GetSqlStringCommand(sql);
//
No need to open the connection; just make the call.
DataSet customerDataSet = db.ExecuteDataSet(cmd);
但是,也有另外一种情况,什么时候关闭连接不是很清楚。例如,ExecuteReader方法。这个方法返回一个实现IDataReader接口的对象。关闭DataReader之后,连接会自动关闭。
Database db
=
DatabaseFactory.CreateDatabase();
DbCommand cmd
=
db.GetSqlStringCommand(
"
Select Name, Address From Customers
"
);
using
(IDataReader reader
=
db.ExecuteReader(cmd))
{
//
Process results
}
7、使用TransactionScope类
Database类中的一些方法使用了.NET 框架的TransactionScope类。这个类自动将数据库调用组合成一个事务,
using
(TransactionScope scope
=
new
TransactionScope(TransactionScopeOption.RequiresNew))
{
int
dRows
=
db.ExecuteNonQuery(CommandType.Text, insertString);
dRows
=
db.ExecuteNonQuery(CommandType.Text, insertString2);
}
这两个ExecuteNonQuery方法插入数据的方法组成一个事务。TransactionScope类创建一个本地的,轻量的事务。假定你在事务中的数据库调用使用同一个连接。这意味着,不用传递DbTransaction实例,只是简单的传递连接,.NET框架自动为你执行的每个command创建事务。
企业库在正常情况下,为每一个请求打开和关系连接。