ADO.NET 2.0 特性






3.33/5 (6投票s)
2007年11月24日
6分钟阅读

53277
本文总结了 ADO.NET 2.0 的新增和更新特性,ADO.NET 2.0 随 .NET Framework 2.0 一起发布。
引言
本文总结了 ADO.NET 2.0 的新增和更新特性,ADO.NET 2.0 随 .NET Framework 2.0 一起发布。在接下来的文章中,我将通过示例详细讨论这些特性。
以下是 ADO.NET 的新增和更新列表。
1. 批量复制操作
引言
将数据从一个数据源批量复制到另一个数据源是 ADO.NET 2.0 新增的功能。批量复制类提供了一种最快的方式来在源和目标之间传输数据集。
每个 ADO.NET 数据提供程序都提供批量复制类。例如,在 SQL.NET 数据提供程序中,批量复制操作由 SqlBulkCopy 类处理,如图 1 所示。从图 1 可以看出,数据可以从一个数据源复制到四种类型之一——DataReader、DataSet、DataTable 或 XML。
 
 
使用批量复制操作,您可以在同一 SQL Server 中的两个表之间、两个不同的 SQL Server 之间,甚至两种不同类型的数据库服务器之间传输数据。
从源填充数据
将数据从一个数据源批量复制到另一个数据源的第一步是从源数据库填充数据。这些源数据可以填充到 DataSet、DataTable 或 DataReader 中。
// Select data from Products table
cmd = new SqlCommand("SELECT * FROM Products", source);
// Execute reader
SqlDataReader reader = cmd.ExecuteReader();
创建 SqlBulkCopy 对象
在 ADO.NET 2.0 中,每个数据提供程序都有一个批量复制操作类,提供批量复制相关的功能。例如,SQL 数据提供程序有一个 SqlBulkCopy 类。
SqlBulkCopy 类的构造函数将连接字符串或 SqlConnection 对象作为第一个参数,该参数定义了目标数据源。创建对象后,需要将 DestinationTableName 属性设置为要复制数据的表。
// Create SqlBulkCopy
SqlBulkCopy bulkData = new SqlBulkCopy(destination);
// Set destination table name
bulkData.DestinationTableName = "BulkDataTable";
将数据复制到目标
SqlBulkCopy 类提供了 WriteToServer 方法,该方法用于将数据从 DataReader、DataSet 或 DataTable 写入目标数据源。
bulkData.WriteToServer(reader);
在此代码中,我从源数据源填充 DataReader 对象。您还可以将数据填充到 DataSet 中,并将 DataSet 作为 WriteToServer 方法的输入参数。您还可以传递 XML 对象,或者从 XML 文档填充数据到 DataSet 中。
关闭 SqlBulkCopy 对象
SqlBulkCopy 的 Close 方法关闭批量复制操作。
bulkData.Close();
完整源代码
下表列出了完整的源代码。
// Create source connection
SqlConnection source = new SqlConnection(connectionString);
// Create destination connection
SqlConnection destination = new SqlConnection(connectionString);
// Clean up destination table. Your destination database must have the
// table with schema which you are copying data to.
// Before executing this code, you must create a table BulkDataTable
// in your database where you are trying to copy data to.
SqlCommand cmd = new SqlCommand("DELETE FROM BulkDataTable", destination);
// Open source and destination connections.
source.Open();
destination.Open();
cmd.ExecuteNonQuery();
// Select data from Products table
cmd = new SqlCommand("SELECT * FROM Products", source);
// Execute reader
SqlDataReader reader = cmd.ExecuteReader();
// Create SqlBulkCopy
SqlBulkCopy bulkData = new SqlBulkCopy(destination);
// Set destination table name
bulkData.DestinationTableName = "BulkDataTable";
// Write data
bulkData.WriteToServer(reader);
// Close objects
bulkData.Close();
destination.Close();
source.Close();
注意
执行此代码之前,请确保您的数据库中有一个名为 BulkDataTable 的表,其架构与 Products 表相同。
2. 批量更新
批量更新可以通过一次服务器往返处理多个批量更新来极大地提高性能,而不是像数据库服务器支持批量更新功能那样进行多次往返。UpdateBatchSize 属性提供要批量更新的行数。此值可以设置为十进制的上限。
ADO.NET 2.0 的批量更新以提高性能
当您使用 .NET 1.1 中的 DataAdapter 更新数据库时,每个命令都单独发送到数据库。这导致了许多往返数据库的操作。
ADO.NET 2.0 引入了批量更新的概念,它允许您指定一次发送到数据库的命令数量。如果使用得当,这可以通过减少往返数据库的次数来提高数据访问层的性能。
DataAdapter.UpdateBatchSize 属性
DataAdapter 有一个 UpdateBatchSize 属性,允许您设置每次请求发送到数据库的命令数量。
- UpdateBatchSize = 1,禁用批量更新
- UpdateBatchSize = X,其中 X > 1,一次将 X 条语句发送到数据库
- UpdateBatchSize = 0,一次发送服务器允许的最大语句数
Command.UpdatedRowSource 属性
使用批量模式时,命令的 UpdatedRowSource 属性只能设置为 UpdatedRowSource.None 或 UpdatedRowSource.OutputParameters。
使用 Northwind 的批量更新教程
您可以在 Northwind 数据库上测试批量更新,方法是模拟对 Categories 表的更新。
首先,从 Categories 表获取数据。下面的代码获取信息并将其放入非类型化的 DataSet 中。
SqlConnection connection = new SqlConnection("...");
SqlDataAdapter adapter = 
    new SqlDataAdapter("SELECT * FROM Categories",connection);
DataSet ds = new DataSet();
adapter.Fill(ds);
模拟修改每个类别的 CategoryName,以便有东西可供更新。
foreach (DataRow dr in ds.Tables[0].Rows)
{
 string categoryName = dr["CategoryName"].ToString();
    dr["CategoryName"] = categoryName;
}
为 SqlDataAdapter 构建一个更新命令来更新数据,并将其分配给适配器的 UpdateCommand 属性。
SqlCommand command = new SqlCommand();
command.CommandText = "Update Categories Set CategoryName = @CategoryName
WHERE CategoryID = @CategoryID";
command.Parameters.Add(new SqlParameter ("@CategoryID",
                 SqlDbType.Int)).SourceColumn = "CategoryID";
command.Parameters.Add(new SqlParameter
      ("@CategoryName", SqlDbType.NVarChar, 15)).SourceColumn = "CategoryName";
adapter.UpdateCommand = command;
将 UpdatedBatchSize 和 UpdatedRowSource 设置为适当的值。对于 Categories 表,其中只有八条记录,我们已全部更改。为方便测试,我将 UpdatedBatchSize 设置为 2。
adapter.UpdateBatchSize = 2;
command.UpdatedRowSource = UpdateRowSource.None;
执行更新过程
adapter.Update(ds);
挂钩 DataAdapter 的 DataRowUpdating 和 DataRowUpdated 事件
我像下面这样挂钩 DataAdapter 的 DataRowUpdating 和 DataRowUpdated 事件:
adapter.RowUpdating +=
    new SqlRowUpdatingEventHandler(adapter_RowUpdating);
adapter.RowUpdated +=
    new SqlRowUpdatedEventHandler(adapter_RowUpdated);
private void adapter_RowUpdated(object sender, SqlRowUpdatedEventArgs e)
{
    _countUpdated++;
}
void adapter_RowUpdating(object sender, SqlRowUpdatingEventArgs e)
{
    _countUpdating++;
}
不使用批量更新时,这两个事件都会触发八次,一次针对每个要更新的行。
然而,使用批量更新时,RowUpdated 将每个批量更新只调用一次(8 行 / 2 次更新/批 = 4 次)。RowUpdating 将按通常的八次调用。
结论
批量更新可以通过减少往返数据库的次数来提高数据访问层的性能。
3. 数据分页
现在,命令对象有一个新的执行方法,称为 ExecutePageReader。此方法接受三个参数——CommandBehavior、startIndex 和 pageSize。因此,如果您想获取从第 101 行到第 200 行的行,只需使用起始索引 101 和页面大小 100 调用此方法即可。
4. 连接详细信息
现在,您可以通过将 Connection 的 StatisticsEnabled 属性设置为 True 来获取有关连接的更多详细信息。Connection 对象提供了两个新方法——RetrieveStatistics 和 ResetStatistics。RetrieveStatistics 方法返回一个 HashTable 对象,其中包含有关连接的信息,如传输的数据、用户详细信息、游标详细信息、缓冲区信息和事务。
5. DataSet.RemotingFormat 属性
当 DataSet.RemotingFormat 设置为 binary 时,DataSet 将以二进制格式而不是 XML 标记格式进行序列化,这显著提高了序列化和反序列化操作的性能。
6. DataTable 的 Load 和 Save 方法
在 ADO.NET 的先前版本中,只有 DataSet 具有 Load 和 Save 方法。Load 方法可以从 XML 等对象加载数据到 DataSet 对象,Save 方法将数据保存到持久媒体。现在 DataTable 也支持这两个方法。
您还可以通过使用 Load 方法将 DataReader 对象加载到 DataTable 中。
7. 新数据控件
在工具箱中,您将看到这些新控件——DataGridView、DataConnector 和 DataNavigator。(参见图 1。)现在使用这些控件,您可以为数据绑定控件中的数据提供导航(分页)支持。
 
 
8. DbProvidersFactories 类
此类提供了机器上可用数据提供程序的列表。您可以使用此类及其成员来查找最适合您数据库的数据提供程序,以便编写与数据库无关的应用程序。
9. 自定义数据提供程序
通过提供工厂类,ADO.NET 现在扩展了对自定义数据提供程序的支持。现在您不必编写依赖于数据提供程序的代码。您可以使用数据提供程序的基类,让连接字符串为您完成工作。
10. DataReader 的新 Execute 方法
现在命令对象支持更多的执行方法。除了旧的 ExecuteNonQuery、ExecuteReader、ExecuteScaler 和 ExecuteXmlReader 之外,新的执行方法是 ExecutePageReader、ExecuteResultSet 和 ExecuteRow。图 2 显示了 ADO.NET 2.0 中命令对象支持的所有执行方法。
 
 
Execute 方法。摘要
ADO.NET 2.0 为开发人员提供了许多新的和改进的功能,以提高性能并减少代码量。
