使用类型化DataSet时,通过延迟DataTable的Expression列计算来提高Fill的性能
在使用非强类型普通DataSet的时候,如果要向DataTable中含有Expression列的话,一般都采用下面这样的步骤来提高应用程序的性能。
1.首先使用DataAdapter.Fill方法填充一个DataTable。
2.然后在通过编码向DataTable中添加Expression列。
3.将这个DataTable作为数据源绑定到相关的控件上(比如DataGridView)。
1.首先使用DataAdapter.Fill方法填充一个DataTable。
2.然后在通过编码向DataTable中添加Expression列。
3.将这个DataTable作为数据源绑定到相关的控件上(比如DataGridView)。
示例代码:
1 dataAdapter.Fill(dt);
2 dt.Columns.Add("ItemTotal", typeof(Decimal), "Quantity * UnitPrice");
3 dataGridView.DataSource = dt;
2 dt.Columns.Add("ItemTotal", typeof(Decimal), "Quantity * UnitPrice");
3 dataGridView.DataSource = dt;
当使用强类型类型化DataSet的时候,由于DataTable中的Expression列已经创建好了,就得另辟方法来解决性能问题。方法的大体思路是这样的:
1.在调用Fill方法之前, 遍历DataTable的所有列,如果该列为Expression则以该列名称作为Key,Expression表达式作为Value存入一个Hashtable中,然后将该列的Expression属性设置为空。
2.调用DataAdapter(或者DataTableAdapter)的Fill方法来填充这个DataTable。
3.最后再遍历DataTable的所有列,判断Hashtable["列名"]是否存在, 如果存在,则将相应的Value值赋给该列的Expression属性,最后清空Hashtable。
示例代码:
1Hashtable expressionKey = new Hashtable();
2
3//规避DataTable的Expression列,减轻Fill时的负担
4for (int i = 0; i < targetTable.Columns.Count; i++)
5{
6 if (targetTable.Columns[i].Expression != string.Empty)
7 {
8 expressionKey.Add(targetTable.Columns[i].ColumnName, targetTable.Columns[i].Expression);
9 targetTable.Columns[i].Expression = string.Empty;
10 }
11}
12
13tableAdapter.Fill(targetTable);
14
15//恢复DataTable的Expression列,Fill完了之后进行统一的表达式计算
16for (int i = 0; i < targetTable.Columns.Count; i++)
17{
18 if (expressionKey.ContainsKey(targetTable.Columns[i].ColumnName))
19 {
20 targetTable.Columns[i].Expression =
21 (String)expressionKey[targetTable.Columns[i].ColumnName];
22 }
23}
24
25expressionKey.Clear();
2
3//规避DataTable的Expression列,减轻Fill时的负担
4for (int i = 0; i < targetTable.Columns.Count; i++)
5{
6 if (targetTable.Columns[i].Expression != string.Empty)
7 {
8 expressionKey.Add(targetTable.Columns[i].ColumnName, targetTable.Columns[i].Expression);
9 targetTable.Columns[i].Expression = string.Empty;
10 }
11}
12
13tableAdapter.Fill(targetTable);
14
15//恢复DataTable的Expression列,Fill完了之后进行统一的表达式计算
16for (int i = 0; i < targetTable.Columns.Count; i++)
17{
18 if (expressionKey.ContainsKey(targetTable.Columns[i].ColumnName))
19 {
20 targetTable.Columns[i].Expression =
21 (String)expressionKey[targetTable.Columns[i].ColumnName];
22 }
23}
24
25expressionKey.Clear();
最后测试一下效果如何
使用Northwind数据库的Order Details表创建一个强类型类型化DataSet来进行测试(约2000多条数据)。
追加了一个ItemTotal列 Expression = UnitPrice * Quantity
经测试性能比直接Fill大概提高 30%左右, 效果还是比较明显的。
顺便推荐一篇MSDN文章: 在 .NET 中使用类型化 DataSet 实现 Data Transfer Object