将DataTable.Rows复制到DataRow []。更快的方式然后Select()具有相同的功能?

时间:2012-09-17 10:08:18

标签: c# .net-4.0 dataset asp.net-4.0

我现在遇到了一个非常古老的系统问题。 (!它已经超过7年了,我没有预算和资源来对结构进行更大的改变,所以决定尽可能多地改进旧逻辑。!)

我们有自己编写的gridcontrol。基本上它就像一个普通的ASP.NET网格,可以添加,更改,删除元素。

问题是网格有BindGrid()方法,为了进一步使用,数据源表的行被复制到DataRow[]。我需要保留DataRow[],但我想实现将源从表中复制到数组中的最佳方法。

目前的解决方案:

DataRow[] rows = DataSource.Select("1=1", SortOrderString);

正如我迄今为止所经历的那样,如果我需要获得指定的排序,这可能是最好的方式(如果它有更快的方式,我也会感兴趣。)

但是有一些简化页面,不需要SortOrder。

所以我可以为排序顺序制作两个方法,而为没有排序顺序。 真正的问题是第二个:

 DataRow[] rows = DataSource.Select("1=1");

因为它很慢。我做了一些测试,它比慢15倍然后是CopyTo()解决方案:

DataRow[] rows = new DataRow[DataSource.Rows.Count];
DataSource.Rows.CopyTo(rows,0);

我想用更快的方式,但是当我进行测试时,一些旧功能只是崩溃了。看来,还有另外一个区别,我现在才注意到的: Select()获取接受RowChanges的行。

因此,如果我删除了一行,并且我没有使用AcceptRowChanges()我不能这样做),那么使用Select("1=1")行就是DataSource但不在DataRow[]

有一个简单的.CopyTo()行就在那里,这对我来说是个坏消息。

我的问题是:

1)Select(“1 = 1”)是RowChanges获取行的最佳方法吗? (我有点怀疑,因为它就像是6岁的部分)

2)如果1)不是,是否有可能以比.Select(“1 = 1”)相同的结果实现更快的方式?

更新

这是一个非常基本的测试应用程序,我用于速度测试:

DataTable dt = new DataTable("Test");

dt.Columns.Add("Id", typeof (int));
dt.Columns.Add("Name", typeof(string));

for (int i = 0; i < 10000; i++)
{
    DataRow row = dt.NewRow();
    row["ID"] = i;
    row["Name"] = "Name" + i;
    dt.Rows.Add(row);
}

dt.AcceptChanges();
DateTime start = DateTime.Now;

DataRow[] rows = dt.Select();

/*DataRow[] rows = new DataRow[dt.Rows.Count];
dt.Rows.CopyTo(rows,0);*/

Console.WriteLine(DateTime.Now - start);

1 个答案:

答案 0 :(得分:1)

您可以在没有参数的情况下致电SelectDataRow[] allRows = DataSource.Select();这肯定会比"1=1"更有效率,因为它会应用无意义的RowFilter

另一种方法是使用Linq-To-DataSet订购和过滤DataTable。这不是更有效,但更具可读性和可维护性。

我还没有任何示例或衡量标准,但很明显,RowFilter "1=1"比没有Select更贵。 public Select(DataTable table, string filterExpression, string sort, DataViewRowState recordStates) { this.table = table; this.IndexFields = table.ParseSortString(sort); this.indexDesc = Select.ConvertIndexFieldtoIndexDesc(this.IndexFields); // following would be omitted if you would use DataSource.Select() without "1=1" if (filterExpression != null && filterExpression.Length > 0) { this.rowFilter = new DataExpression(this.table, filterExpression); this.expression = this.rowFilter.ExpressionNode; } this.recordStates = recordStates; } 以这种方式实现:

DataRow[] allRows = DataSource.Select("", "", DataViewRowState.CurrentRows | DataViewRowState.Deleted);

如果您还希望能够选择当前未被接受的行,则可以使用Select的重载:

AcceptChanges

即使尚未调用{{1}},也会选择包含已删除行的所有行。