我现在遇到了一个非常古老的系统问题。 (!它已经超过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);
答案 0 :(得分: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;
}
以这种方式实现:
DataRow[] allRows = DataSource.Select("", "", DataViewRowState.CurrentRows | DataViewRowState.Deleted);
如果您还希望能够选择当前未被接受的行,则可以使用Select
的重载:
AcceptChanges
即使尚未调用{{1}},也会选择包含已删除行的所有行。