在本系列我们用类型化的DataSets来构建数据访问层。就像在第一章探讨的那样,类型化DataSets的DataTables用作存储数据的“仓库”,而TableAdapters作为连接数据库的通道,以检索、修改数据.TableAdapters 将处理数据库的很多复杂的细节进行了封装,将我们解脱出来,免去了写代码连接数据库、发出命名、向DataTable填充数据的痛苦.
不过在某些时候我们需要深入的探究TableAdapter,直接写代码处理ADO.NET对象.在第61章《在事务里对数据库修改进行封装》里我们向TableAdapter添加了多个方法以开启、提交、回滚ADO.NET事务.这些方法都使用内在的、手动创建的SqlTransaction对象来对TableAdapter的SqlCommand对象进行赋值.
在本文,我们将考察如何访问TableAdapter的“数据库连接”和“数据库命令”级的设置.具体来说,我们将向ProductsTableAdapter添加函数,以访问“连接字符串”(connection string)和“命令过期时间”(command timeout)设置.
用ADO.NET处理数据
微软.NET Framework包含了很多处理数据的特殊用途的类。这些类用System.Data namespace来进行创建,其中就包括ADO.NET classe类,一些ADO.NET名下的类需要依赖某个特定的data provider才能工作.你可以想象在ADO.NET classes类和某个数据存储(data store)之间,有一个data provider充当连接通道(communication channel)以供传递信息.data provider包括OleDb 、ODBC, 以及其它一些专门设计来连接某种特定数据库系统的data provider.举个例子,我们不能用OleDb来连接一个Microsoft SQL Server数据库.而SqlClient就可以,因为它是经过优化的专门设计来连接SQL Server的.
当编程访问数据时,通常使用下面的模式:
1.新建数据库连接
2.发出命令
3.用SELECT查询来返回记录
以上3步每步都有单独的ADO.NET classes类来执行.比如连接数据库用SqlConnection class类;要发出INSERT, UPDATE, DELETE,或SELECT命令,用SqlCommand class类.
除了第61章《在事务里对数据库修改进行封装》外,我们都没有自己写任何ADO.NET代码,因为TableAdapters自动生成的代码包含了一些必要的功能:连接数据库、发出命令、检索数据、填充DataTables.但是有时我们要自己定制这些设置.在接下来的几步我们将探究TableAdapters内部使用的ADO.NET对象.
第一步:考察Connection属性
每个TableAdapter class类都有一个Connection属性,用于指定数据库连接信息.该属性的数据类型以及ConnectionString的值根据TableAdapter设置向导所做的配置而定.我们还记得,当向类型化的DataSet添加一个TableAdapter时,向导要我们指定数据源(见图1).在下拉列表里列出了web.config文件指定连接的数据库,以及服务器资源管理器的Data Connections里的数据库.如果我们要连接的数据库没有出现在下拉列表里,点“New Connection”按钮,以提供必需的连接信息.
图1:TableAdapter设置向导的第一步
我们化点时间来查看TableAdapter的Connection属性的代码,就像在第一章《创建一个数据访问层》里探讨的一样,我们可以在Class View窗口里查看自动生成的TableAdapter代码,转到相应的类,再双击成员名(member name)即可.
打开“View”菜单,选中“Class View”(或按住Ctrl+Shift+C).在Class View窗口的上半部分里,选中NorthwindTableAdapters命名空间,再选中ProductsTableAdapter class类.这将在下半部分显示出ProductsTableAdapter的成员,如图2所示.双击Connection属性以查看代码。
图2:双击Connection以查看自动生成的代码
TableAdapter的Connection属性以及其它与连接相关的代码如下:
private System.Data.SqlClient.SqlConnection _connection; private void InitConnection() { this._connection = new System.Data.SqlClient.SqlConnection(); this._connection.ConnectionString = ConfigurationManager.ConnectionStrings["NORTHWNDConnectionString"].ConnectionString; } internal System.Data.SqlClient.SqlConnection Connection { get { if ((this._connection == null)) { this.InitConnection(); } return this._connection; } set { this._connection = value; if ((this.Adapter.InsertCommand != null)) { this.Adapter.InsertCommand.Connection = value; } if ((this.Adapter.DeleteCommand != null)) { this.Adapter.DeleteCommand.Connection = value; } if ((this.Adapter.UpdateCommand != null)) { this.Adapter.UpdateCommand.Connection = value; } for (int i = 0; (i < this.CommandCollection.Length); i = (i + 1)) { if ((this.CommandCollection[i] != null)) { ((System.Data.SqlClient.SqlCommand) (this.CommandCollection[i])).Connection = value; } } } }