哪个是最有效的DataSet查询操作?

时间:2017-01-23 19:50:59

标签: c# .net performance linq

以这种方式创建查询效率更高:

var ordersDataTable = dataSet.Tables["Orders"];

var query = ordersDataTable.Select("OrderType = '" + orderType + "' AND Status = 'ACT'");

或者使用Linq,像这样:

IEnumerable<DataRow> query =
    from order in dataSet.Tables["Orders"].AsEnumerable()
    where (order.Field<string>("OrderType") == "'" + orderType + "'") &&
          (order.Field<string>("Status") == "'ACT'")
    select order;

如果您要处理返回的行,请执行以下操作:

foreach (var p in query)
{...}

关于何时应用过滤器(或者同时创建&#34;生成器&#34;以及每次是否重新评估order.Field(&#34; OrderType&#34;)结构的问题)当你迭代。

数据来自加载到DataSet对象中的XML文件。

2 个答案:

答案 0 :(得分:2)

LINQ方法将为每次迭代计算order.Field<string>("OrderType"),包括与未出现在结果中的行对应的迭代。此外,它将评估具有匹配订单类型的每一行的order.Field<string>("Status")。此行为很难优化,因为order参数在每次迭代中都不同。您可以使用DataColumn

的重载来加快处理速度
var ordTypeCol = ordersDataTable.Columns["OrderType"];
var ordStatusCol = ordersDataTable.Columns["Status"];
var query =
    from order in dataSet.Tables["Orders"].AsEnumerable()
    where (order.Field<string>(ordTypeCol) == orderType) &&
          (order.Field<string>(ordStatusCol) == "ACT")
    select order;

注意:下面的连接表达式

"'" + orderType + "'"

也将在每次迭代中进行评估。但是,可以通过在where子句之外创建变量来优化此操作。很可能这种连接是不必要的,因为LINQ版本不会解析你的文字,所以它不需要围绕值的引号(感谢,Ivan Stoev,用于评论)。

答案 1 :(得分:1)

这两种技术都会导致&#34;表扫描&#34;包含从XML中提取的数据的内存结构。因此,就纯查询效率而言,它们应该非常接近。

但是,使用DataTable.Select方法需要框架来解析传入的字符串。这可能会增加少量开销。此外,它在编译时错误检测方面更成问题,因为表达式不会被解析直到运行时。使用Linq方法可确保强类型检查和更少的运行时问题。

此外,使用Linq方法,您不必连接(或转义)语法,例如您不需要使用"'" + myString + "'",只需使用myString即可。这不仅更容易打字和阅读,而且可以防范injection attacks