0

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

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

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

目前的解决方案:

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

正如我到目前为止所经历的那样,如果我需要获得指定的排序,那可能是最好的方法(我也很感兴趣它是否有更快的方法。)

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

所以我可以制作两种方法,一种用于排序顺序,另一种用于没有排序顺序。真正的问题是第二个:

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

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

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);
4

1 回答 1

1

您可以Select不带参数调用:DataRow[] 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;
}

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

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

这将选择所有行,包括已删除的行,即使AcceptChanges尚未调用也是如此。

于 2012-09-17T10:21:07.113 回答