您的位置:首页 > 其它

企业程序库(三)——数据访问应用程序块

2008-05-13 16:48 316 查看
数据访问应用程序块简介

Enterprise Library Data Access Application Block 1.0 版可以简化实现通用数据访问功能的开发任务。应用程序可以在很多情况下使用应用程序块,例如读取显示数据、获得通过应用程序层的数据,以及将更改过的数据提交回数据库系统等。应用程序块包括对存储过程和内嵌 SQL 以及常见内务处理任务(例如,管理连接、创建与缓存封装在应用程序块的方法中的参数)的支持。换句话说,数据访问应用程序块提供对最常用的 ADO.NET 功能的访问。

该应用程序块还简化了可移植应用程序代码的开发,允许多个数据库服务器(包括 Microsoft SQL Server、Oracle 和 DB2中的代码保持一致。为此,可以使用抽象基类来定义公共接口并提供数据访问方法的多种实现,为一种数据库(例如 SQL Server£©编写的应用程序看起来与为另一种数据库(例如 oracle)编写的应用程序相同。通过使用数据访问应用程序块并遵循本文档中的准则,您的代码大部分都可以移植。

另一个功能是,应用程序代码可以通过名称(例如,“Customer”或“Inventory”)来引用特定的数据库。更改应用程序配置中的名称允许开发人员以不同的数据库配置来使用他们的应用程序,而无需重新编译他们的代码。

数据访问应用程序块具有以下功能:

•它可以减少编写样本代码以执行标准任务的需要。

•它有助于在应用程序和整个企业中维护一致的数据访问做法。

•它可以降低更改物理数据库目标的难度。

•它使开发人员免于学习不同类型数据库的不同编程模型。

•将应用程序移植到不同类型的数据库时,它可以减少需要重新编写的代码数量。

常见情况

开发人员经常要编写使用数据库的应用程序。因为很常见,所以开发人员可能会发现自己为每个应用程序反复编写了相同的代码。另外,这些应用程序可能需要与不同类型的数据库一起工作。虽然任务相同,但必须要改写代码以符合每个数据库编程模型的要求。数据访问应用程序块通过提供最常见数据访问任务的实现,从而解决了这些问题。开发人员只需完成以下工作:

1.创建数据库对象。

2.提供命令的参数(如果需要)。

3.调用适当的方法。

这些方法都进行了性能优化。它们也可以移植。数据访问应用程序块可以透明地与 SQL Server、DB2 和 oracle 数据库一同工作。

读者要求

该指南专为软件架构师和软件开发人员而编写。要充分利用该指南,您应该了解以下技术:

•Microsoft Visual C# 开发工具或 Microsoft Visual Basic 开发系统

•.NET Framework

•Microsoft SQL Server、Oracle 或 DB2 数据库

1.0 版本的主要特点

Enterprise Library Data Access Application Block 1.0 版包含以下新功能:

•用于管理配置设置的图形工具

•支持多个数据库系统,并且能够添加其他系统

•分别抽象数据库和连接字符串的工厂和命名实例

•对参数缓存的支持已扩展为允许应用程序清除缓存

从先前版本的数据访问应用程序块迁移

早期版本的数据访问应用程序块用户应该了解企业程序库版本针对的多种情况。虽然当前版本是基于从早期版本获得的知识和反馈而构建的,但它在如何解决那些情况方面有了重大改变。

以下列表描述了企业程序库版本的数据访问应用程序块与早期版本的区别:

•早期版本应用程序块中的静态 helper 方法已经由实例化数据访问对象的方法所取代。

•现在还提供了接受新数据访问对象的另一种样式的重载。在使用该样式时,会通过两种重载公开所有的数据访问功能,一种是在事务外执行命令时使用,另一种是在事务内执行命令时使用。

•每个数据访问方法的许多重载都已简化。

•特定于数据库的对象由工厂创建,它使用配置信息来确定要创建对象的类型。

•连接字符串信息已经移到配置文件,在调用方法时不再使用。使用企业程序库配置控制台可允许您配置数据库,如果需要,还可加密存储中的配置信息。

•现在用一个单独的类来表示命令信息。开发人员创建并初始化命令对象,然后将其传递到 Database 类的适当方法中。

以下代码演示了某个应用程序使用数据访问应用程序块来执行一条返回数据集的数据库查询。

[C#]

myDataSet = DatabaseFactory.CreateDatabase(\"Sales\").ExecuteDataSet(\"GetOrdersByCustomer\", myCustomerId );

[VB]

myDataSet = DatabaseFactory.CreateDatabase(\"Sales\").ExecuteDataSet(\"GetOrdersByCustomer\", myCustomerId);
请注意,开发人员编写的代码通过名称引用数据库。实际的数据库类型和连接字符串存储在配置中。

系统要求

要使用数据访问应用程序块来开发应用程序,您需要以下各项:

•Microsoft Windows 2000¡¢Windows XP Professional 或 Windows Server 2003 操作系统

•Microsoft .NET Framework 1.1

•Microsoft Visual Studio .NET 2003

•运行 SQL Server 7.0 或更高版本、Oracle 9i 或 DB2 的数据库服务器(如果您使用 DB2 数据库,则还需要 IBM UDB 8.1.2 数据提供程序)

数据访问应用程序块的依赖项

企业程序库提供的应用程序块设计为能够彼此配合使用。有时,应用程序块依赖于其他应用程序块和企业程序库中包含的代码。数据访问应用程序块具有以下依赖项:

配置应用程序块。数据访问应用程序块使用配置应用程序块来读取其配置信息。

通用程序库功能,例如规范。它提供了各种功能来公开用于系统管理的事件和数据。

默认情况下,该应用程序块使用 XML 文件来存储配置信息。修改这些信息的推荐方法是使用企业程序库配置控制台。

您可以使用企业程序库配置控制台来加密和保护包含连接字符串的数据库配置信息。连接字符串可以包含密码、网络地址及其他敏感信息。要了解有关加密配置设置的更多信息,请参阅企业程序库配置应用程序块文档。

数据访问应用程序块的设计

数据访问应用程序块旨在实现以下目标:

•封装用于执行最常见数据访问任务的逻辑

•使开发人员免于编写常见数据访问任务的重复代码

•将自定义代码的需求降至最少

•集成数据访问的最佳做法,如 .NET Data Access Architecture Guide 中所述。

•执行效率不超过 ADO.NET 的 5%

•拥有较少的对象和类

•确保所有应用程序块的功能对于不同类型的数据库都一样有效

•确保在数据访问方面,无论为哪一种类型的数据库编写应用程序均相同

•使用配置中存储的数据库连接信息

设计要点

图 1 展示了数据访问应用程序块中关键类的相互关系。





图 1. 数据访问应用程序块的设计

抽象基类 Database 定义了公共接口,并提供了数据访问方法的多种实现。SqlDatabaseOracleDatabaseDb2Database 类均派生于 Database 类。它们为其各自的数据库服务器系统提供方法,这包括常见功能(根据数据库的不同,其实现也不同)以及该数据库系统所特有的功能。

数据库命令和参数在数据库系统中的处理是不同的。抽象类 DbCommandWrapper 提供特定数据库类的接口定义,它将包装 IDbCommand 并提供参数处理。

DatabaseFactory 类提供了静态方法 CreateDatabase,以封装创建适当 Database 对象的逻辑。通过使用工厂来创建正确的数据库对象,客户端代码就不会绑定到特定的数据库类型。

DatabaseFactory 类使用配置应用程序块来检索所需的配置信息,包括要创建的、派生于 Database 的特定类的完全限定类型名和连接字符串。

该应用程序块支持动态发现参数。这种发现机制需要往返于数据库系统。ParameterCache 类允许缓存参数信息,因此可以避免同一存储过程后续调用的往返行程。

测试驱动

开发数据访问应用程序块的目的是,分析常见的企业开发难题以及提供针对这些难题的成功解决方案。然而,因为每个应用程序都是唯一的,所以您会发现该应用程序块并不适合每个应用程序。为了评估该应用程序块并确定它对您项目的适用性,Microsoft 建议您至少用半天的时间来研究该应用程序块。推荐的评估方法如下:

1.下载企业程序库。

2.安装企业程序库,并编译所有的应用程序块和工具。

3.阅读文档的“Introduction”和“Scenarios and Goals”部分。

4.运行脚本以配置应用程序块的快速入门示例。

5.编译并运行快速入门示例,然后通读文档中相关 “QuickStart Walkthroughs”和“Key Scenarios” 的部分。

6.如果应用程序块看起来很适合您的应用程序,则尝试使用该应用程序块在您的应用程序或丢弃原型 (throw-away prototype) 应用程序中实现一个简单的用例。

Data Access Application Block使用向导:

1.增加对Microsoft.Practices.EnterpriseLibrary.Data.dll和Microsoft.Practices.EnterpriseLibrary.Configuration.dll的引用,并在代码在添加:

using Microsoft.Practices.EnterpriseLibrary.Data;

2.调用代码示例:

(1) ExecuteDataSet方法

Database db = DatabaseFactory.CreateDatabase();

DataSet dsCustomers = db.ExecuteDataSet(CommandType.Text, "Select * From Customers" );

customerGrid.DataSource = dsCustomers.Tables[0];

(2) ExecuteReader方法

Database db = DatabaseFactory.CreateDatabase();

string sqlCommand = "Select top 5 * From Customers";

DBCommandWrapper dbCommandWrapper = db.GetSqlStringCommandWrapper(sqlCommand);

StringBuilder readerData = new StringBuilder();

using (IDataReader dataReader = db.ExecuteReader(dbCommandWrapper))

{

while (dataReader.Read())

{

readerData.Append(dataReader["ContactName"]);

readerData.Append(Environment.NewLine);

}

}

txtResult.Text = readerData.ToString();

为了执行SQL语句,上述代码使用GetSqlStringCommandWrapper方法创建合适command wrapper对象,然后作为参数传递给ExecuteReader方法。

(3) ExecuteNonQuery方法

Database db = DatabaseFactory.CreateDatabase();

string sqlCommand = "getProductDetails";

DBCommandWrapper dbCommandWrapper = db.GetStoredProcCommandWrapper(sqlCommand);

// Add paramters

int productID=1;

// Input parameters can specify the input value

dbCommandWrapper.AddInParameter("@ProductID", DbType.Int32, productID);

// Output parameters specify the size of the return data

dbCommandWrapper.AddOutParameter("@ProductName", DbType.String, 40);

dbCommandWrapper.AddOutParameter("@UnitPrice", DbType.Currency, 8);

dbCommandWrapper.AddOutParameter("@QtyPerUnit", DbType.String, 20);

db.ExecuteNonQuery(dbCommandWrapper);

// Row of data is captured via output parameters

string results = string.Format(CultureInfo.CurrentCulture, "{0}, {1}, {2:C}, {3} ",

dbCommandWrapper.GetParameterValue("@ProductID"),

dbCommandWrapper.GetParameterValue("@ProductName"),

dbCommandWrapper.GetParameterValue("@UnitPrice"),

dbCommandWrapper.GetParameterValue("@QtyPerUnit"));

txtResult.Text = results;

为了执行存储过程,上述代码使用GetStoredProcCommandWrapper方法创建合适的command wrapper对象,然后作为参数传递给ExecuteNonQuery方法。

(4) ExecuteScalar方法

Database db = DatabaseFactory.CreateDatabase();

string sqlCommand = "GetProductName";

int productID=1;

DBCommandWrapper dbCommandWrapper = db.GetStoredProcCommandWrapper(sqlCommand, productID);

// Retrieve ProdcutName. ExecuteScalar returns an object, so

// we cast to the correct type (string).

String productName = (string) db.ExecuteScalar(dbCommandWrapper);

txtResult.Text = productName;

Demo程序界面如下(注意在项目属性窗口中设置Post-build Event Command Line属性值:copy "$(ProjectDir)*.config" "$(TargetDir)"):



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐