我有一个大约50,000行的DataTable,我正在使用DataTable.Select
来检索行。 Select
需要多个AND
条件,包括通配符匹配。我玩过,发现通过多个步骤执行相同的Select
,可以大大减少执行时间,但更改AND
语句的顺序不会影响它。
//This takes ~ 750 ms
DataRow[] results = myDataTable.Select("Field1 LIKE '*" + term1 + "*'" +
"AND Field2 = '" + term2 + "'" +
"AND Field3 = '" + term3 + "'");
//This also takes ~750 ms
DataRow[] results2 = myDataTable.Select("Field3 = '" + term3 + "'" +
"AND Field2 = '" + term2 + "'" +
"AND Field1 LIKE '*" + term1 + "*'");
//This takes 0.415 ms
DataTable table1 = myDataTable.Select("Field3 = '" + term3+ "'").CopyToDataTable();
DataTable table2 = table1.Select("Field2 = '" + term2 + "'").CopyToDataTable();
DataRow [] results3 = table2.Select("Field1 LIKE '*" + term1 + "*'");
我的问题是,有没有办法始终按照从左到右的顺序对SELECT
操作评估AND
条件,以便在步骤之间减少搜索的记录数量?看起来这可能是一个很好的节省时间。谢谢你的想法。
答案 0 :(得分:4)
你可以使用Linq
(注意最慢的条件是最后一个):
IEnumerable<DataRow> rows = myDataTable.AsEnumerable()
.Where(r => r.Field<string>("Field2") == term2
&& r.Field<string>("Field3") == term3
&& r.Field<string>("Field1").Contains(term1));
如果您想根据结果CopyToDataTable
创建新的DataTable来创建ToArray
或保留DataRow[]
并使用foreach
枚举结果而不创建结果,请使用{{1}}一个新的系列。
答案 1 :(得分:1)
Nope ..数据表逐行选择。
您可以将代码写得更短:
DataRow [] results = myDataTable
.Select("Field3 = '" + term3+ "'").CopyToDataTable()
.Select("Field2 = '" + term2 + "'").CopyToDataTable()
.Select("Field1 LIKE '*" + term1 + "*'");
或者......如果你做了一个额外的扩展方法,就像这样:
static public DataRow []选择(此IEnumerable行,字符串过滤器) { return rows.CopyToDataTable()。选择(过滤); }
使用此扩展程序可以缩短您的代码:
DataRow [] results = myDataTable
.Select("Field3 = '" + term3+ "'")
.Select("Field2 = '" + term2 + "'")
.Select("Field1 LIKE '*" + term1 + "*'");
或者:
static public DataRow[] Select(this DataTable dt, string firstFilter, params string[] filters)
{
DataRow[] result = dt.Select(firstFilter);
foreach(string filter in filters)
result = result.CopyToDataTable().Select(filter);
return result;
}
开辟道路:
DataRow [] results = myDataTable.Select(
"Field3 = '" + term3+ "'",
"Field2 = '" + term2 + "'",
"Field1 LIKE '*" + term1 + "*'");