`
bacel5902
  • 浏览: 14677 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
最近访客 更多访客>>
社区版块
存档分类
最新评论

如何高效遍历Dataset

阅读更多
遍历一个Dataset中的数据主要有以下两种方式:

l         方法一

datasetX.moveFirst();

while (!datasetX.isLast()) {

      ... ... ...

      datasetX.moveNext();

}


l         方法二

var record = datasetX.getFirstRecord();

while (record != null) {

       ... ... ...

       record = record.getNextRecord();

}


如无特殊需要,我们推荐使用第二种方法完成对Dataset的遍历。这两种遍历方式的区别在于,第一种遍历方式是通过不断的改变Dataset的当前记录来完成遍历操作的,而第二种遍历方式在遍历的过程中并不会改变Dataset的当前记录。如果此时有任何数据敏感控件绑定在Dataset上,那么,改变Dataset的当前记录将会引起数据敏感控件的刷新动作。如果Dataset中有n条记录,在默认情况下,以第一种方式进行遍历将至少引起相关的数据敏感控件刷新n次,并且当遍历操作结束之后Dataset的当前记录应该总是最后一条记录。

另外,如果被遍历的Dataset是主从绑定关系中的主Dataset。那么直接使用第一种遍历方式将会更加危险,其下的从Dataset可能会随着主Dataset当前记录的改变不断的执行数据加载的动作。数据加载是一种比控件刷新更加耗时的操作。

很多时候,我们使用Dataset遍历是为了修改其中的每一条记录。在这种情况下,如果仅仅是使用此处第二种遍历方式,还远没有达到效率最佳化的目标。此时一定要结合3.4.4中介绍的disableControls()和enableControls()才能得到更好的运行效果。

实测数据:

以两种方式对一个包含2000条记录的Dataset进行遍历。实测环境的CPU为INTER Pentium(R) 1.73G。

l         方法一的耗时为0.256秒。(在进行此方法的测试时我们使用了3.4.4中介绍的disableControls()和enableControls()关闭了数据控件的刷新功能,否则速度将慢得无法忍受)

l         方法二的耗时为0.047秒。

由此可见,两种方式间有接近一个数量级的性能差异。方法二的优势非常明显。

      disableControls()和enableControls()
Dataset的disableControls()方法和enableControls()方法大概是Dorado开发中最常用的优化技巧了。这个方法非常容易使用,而获取的效果也非常显著,他常常可以将一段代码的执行速度提高好几倍甚至更多。

disableControls()表示暂时禁用Dataset的绑定关系,即暂时禁止Dataset向绑定的数据敏感控件发送任何消息,这样数据敏感控件就不会随着Dataset的变化而自动刷新的。enableControls()则正好相反,表示重新允许Dataset向绑定的数据敏感控件发送消息。

disableControls()和enableControls()往往会跟Dataset.refreshControls()方法一起配置使用。refreshControls()的作用是通知所有与改Dataset绑定的数据敏感控件立即进行数据刷新。

假设我们现在要编写一段代码将Dataset中每一条记录的status字段的值设置为completed。未经优化的代码可能是这样的:

var record = datasetX.getFirstRecord();

while (record != null) {

       record.setValue("status", "completed");

       record = record.getNextRecord();

}


假设DatasetX中有n条记录,那么,进行一次这样的遍历将导致相关的数据敏感控件被刷新n次。其实这n次刷新中的前n-1次都是没有任何意义的。

利用disableControls()、enableControls()结合refreshControls()优化之后的代码可能是这样的:

datasetX.disableControls();

try {

      var record = datasetX.getFirstRecord();

      while (record != null) {

            record.setValue("status", "completed");

            record = record.getNextRecord();

      }

}

finally {

      datasetX.enableControls();

      datasetX.refreshControls();

}


这样在执行循环的过程中数据敏感控件完全不会刷新,直到循环结束之后,手工调用refreshControls()通知数据敏感控件进行数据刷新。整个操作将需要进行这一次刷新。

disableControls()、enableControls()并不总是用在循环操作中,只要是针对Dataset的批量操作都考虑使用这种优化技巧。例如下面的这段用于数据复制的未优化代码:

dataset1.setValue("id", "0001");

dataset1.setValue("name", dataset2.getValue("cname"));

dataset1.setValue("sex", (dataset2.getValue("sex"))?"M":"F");

dataset1.setValue("addr", dataset2.getValue("address"));

dataset1.setValue("tel", dataset2.getValue("telephone"));

dataset1.setValue("email", dataset2.getValue("email"));

dataset1.setValue("web", dataset2.getValue("web"));

dataset1.setValue("cmnt", dataset2.getValue("comment"));


我们同样可以使用disableControls()和enableControls()对其进行优化,优化后的代码可能如下:

datasetX.disableControls();

try {

      dataset1.setValue("id", "0001");

      dataset1.setValue("name", dataset2.getValue("cname"));

      dataset1.setValue("sex", (dataset2.getValue("sex"))?"M":"F");

      dataset1.setValue("addr", dataset2.getValue("address"));

      dataset1.setValue("tel", dataset2.getValue("telephone"));

      dataset1.setValue("email", dataset2.getValue("email"));

      dataset1.setValue("web", dataset2.getValue("web"));

      dataset1.setValue("cmnt", dataset2.getValue("comment"));

}

finally {

      datasetX.enableControls();

      datasetX.refreshControls();

}


使用disableControls()和enableControls()时还应该注意这样一个细节,这两个方法的运行机制类似于计数器,而不是通常理解的开关。如果对一个Dataset连续执行两次disableControls()方法,那么也必须再执行两次enableControls()才能重新启用绑定关系,即回复Dataset向数据敏感控件发送消息。

下面的代码可能有助于您理解disableControls()和enableControls()的运行机制:

// 此时绑定可用

datasetX.disableControls();

// 此时绑定被禁用

datasetX.disableControls();

try {

      // 此时绑定被禁用

}

finally {

      datasetX.enableControls();

      // 此时绑定被禁用

      datasetX.enableControls();

      // 此时绑定可用

}


实测数据:

对一个包含50条记录的Dataset进行遍历,并在遍历的过程中修改每一条记录中的5个字段值。

实测环境的CPU为INTER Pentium(R) 1.73G。需要注意的是,此处的测试结果与界面的复杂度密切相关,测试的主要目的是确认未优化代码与优化代码间的性能差异。越是复杂的界面其差异越明显,所以具体的时间值本身参考价值并不大。

l         未经优化的测试代码,其耗时为2.016秒。

var record=dataset1.getFirstRecord();

while (record!=null) {

  record.setValue("field1", "123");

  record.setValue("field2", "234");

  record.setValue("field3", "345");

  record.setValue("field4", "456");

  record.setValue("field5", "567");

  record.post();

  record=record.getNextRecord();

}


l         优化后的测试代码,其耗时为0.25秒。

dataset1.disableControls();

try {

      var record=dataset1.getFirstRecord();

      while (record!=null) {

        record.setValue("field1", "123");

        record.setValue("field2", "234");

        record.setValue("field3", "345");

        record.setValue("field4", "456");

        record.setValue("field5", "567");

        record.post();

        record=record.getNextRecord();

      }

}

finally {

      dataset1.enableControls();

      dataset1.refreshControls();

}



本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/bacel5902/archive/2009/05/06/4154782.aspx
分享到:
评论

相关推荐

    循环遍历dataset

    在本篇文章中,我们将深入探讨如何通过循环遍历DataSet中的数据表、行和列,并针对特定条件进行数据处理。此段代码示例虽然存在一些逻辑上的问题(例如语法错误和逻辑不清晰的地方),但可以作为基础来理解如何遍历...

    C#遍历DataSet中数据的几种方法总结

    当我们需要处理或展示`DataSet`中的所有数据时,遍历就显得尤为重要。下面我们将详细探讨几种遍历`DataSet`中数据的方法。 ### 1. 遍历所有表和它们的所有行与列 ```csharp foreach (DataTable dt in YourDataset....

    C#遍历DataSet控件实例总结

    本文将深入探讨如何使用C#语言遍历DataSet控件,以便高效地访问和操作其中的数据。 首先,遍历DataSet的基本思路是访问其内部的DataTable集合,然后对每个DataTable进行迭代,进一步遍历每一行(DataRow)和每一列...

    C# 集合对象遍历性能测试

    遍历DataSet时,需要考虑其内部的表结构和行、列的关系,因此遍历性能相对较慢,尤其是当DataSet包含多张表或者复杂的数据关系时。 在“TraversalPerformance.csproj”项目中,可能包含了编写这些集合遍历性能测试...

    C#导出DataSet到EXCEL

    4. 遍历DataSet的表和行,将数据填充到工作表中。 5. 保存并关闭工作簿:`workbook.SaveAs("output.xlsx");`,然后`excelApp.Quit();` 如果不想依赖于Office Interop,可以使用其他库,如EPPlus。EPPlus是一个强大...

    多个Dataset导出到一个Excel的多个Sheet中

    5. **填充数据**: 遍历Dataset中的每一行和每一列,将数据写入到对应的Sheet单元格中。这通常通过设置Range对象的值来完成。 6. **保存和关闭**: 保存Workbook到指定的文件路径,然后关闭Excel应用程序,释放资源,...

    NPOI 包解决.net DataSet导出excel问题

    4. 写入数据:遍历DataSet中的DataTable,逐行写入Excel工作表。使用`CreateRow`创建新行,`CreateCell`创建单元格,并将数据设置到单元格中。 5. 设置样式:通过`ICellStyle`接口设置单元格样式,如字体、颜色、...

    将DataSet对象的更新映射会数据库的操作事例

    // 遍历DataSet中的每个DataTable和DataRow,根据实际情况设置参数值 foreach (DataRow row in ds.Tables["members"].Rows) { cmd.Parameters.AddWithValue("@value1", row["column1"]); cmd.Parameters....

    Delphi用DataSet生成Excel,无需OLE和ADO.rar

    5. **写入数据**:遍历DataSet中的每一行数据,将其写入Excel的对应单元格。注意,需要处理不同类型的数据,如字符串、数字、日期等。 6. **格式化和样式**:根据需要,可以为单元格设置格式,如字体、颜色、对齐...

    C# DataSet创建Excel文件(多sheet,支持Excel模板)

    5. **将DataTable转换为Excel工作表**:遍历DataSet中的每个DataTable,使用ExcelWorksheet对象将每个DataTable写入新的工作表。 6. **设置样式和模板**:如果需要支持Excel模板,可以预先创建一个包含格式和样式的...

    电影数据库 DATASET

    在C#中,你可以使用SqlCommand对象执行这个SQL,然后将结果填充到Dataset中,再通过遍历Dataset来显示分页数据。 此外,为了优化分页性能,可以考虑创建索引,特别是对于排序和分页常用的列。在MovieDB表中,如果按...

    C# DataSet和DataTable详解

    C# DataSet和DataTable详解 在C#编程中,DataSet和DataTable是两个非常重要的类,它们都是ADO.NET中数据访问的核心组件。...DataSet和DataTable是C#编程中非常重要的两个类,它们可以帮助我们高效地访问和处理数据。

    C#_DataSet和DataTable详解

    `DataSet`和`DataTable`的使用为C#开发者提供了灵活且高效的数据处理机制,无论是进行数据的本地存储还是与数据库进行交互,都能实现高性能和高灵活性的数据管理。通过理解`DataSet`和`DataTable`的特性和操作方法,...

    Xlsx文件转DataSet

    总结一下,"Xlsx文件转DataSet"是针对大尺寸Excel文件的一种高效读取策略,它通过将Xlsx文件内容转换为.NET的DataSet对象,解决了NPIO等插件在处理大文件时可能遇到的问题。这种方法结合了适合大数据处理的分块读取...

    dataset导出excel

    例如,在C#中,我们可以创建一个Excel应用程序实例,然后循环遍历Dataset的每个DataTable,为每个表创建一个工作表并设置其内容。 设置表头是导出过程中的关键步骤,它使得Excel文件更具可读性。我们可以通过Excel...

    DataSet用法详细

    - 遍历所有列和行:`foreach (DataRow row in tbl.Rows) DisplayRow(row);` 和 `foreach (DataColumn col in tbl.Columns) Console.WriteLine(col.ColumnName);` 4. 数据验证: - DataColumn 属性:可以设置 `...

    Excel上传转成DataSet

    本文将详细讨论如何将Excel文件上传并转换为DataSet,这是一个高效的数据存储和操作结构,适用于.NET开发环境。 标题“Excel上传转成DataSet”指的是利用编程技术将Excel文件中的数据读取并转换为.NET Framework中...

    dataset 详细用法

    3. **查看数据**:遍历 DataTable 的列和行,例如: - 输出列名:`foreach (DataColumn col in tbl.Columns) Console.WriteLine(col.ColumnName);` - 输出行数据:`Console.WriteLine(row["OrderID"]);` - 或者 `...

Global site tag (gtag.js) - Google Analytics