优化使用AsEnumerable和SingleOrDefault的查询

时间:2015-12-10 11:55:13

标签: c# sql extension-methods lambda-calculus

不久前我正在维护的程序中有一个功能请求。基本上它必须用文本文件中的信息填充数据库中的表。这些文件可能非常大,但它很容易做到,因为这些文件被定义为完整的用户数据列表。因此,该表可能会被截断,并且刚刚用文本文件中的数据填充。

但是一周前,我们决定这些文件实际上是当前用户信息的更新,所以现在我必须检索正确的MeteringPointId(如果它确实存在,它只存在一次),然后更新它的信息。如果它不存在,只需像以前一样插入数据。

我这样做的方法是使用数据库中的数据检索完整的数据库表到内存中,然后在最终通过调用datatables更新函数保存更改之前更新该信息。它工作正常,除了找到MeteringPointId的行很慢:

add_filter( 'woocommerce_get_availability', 'custom_get_availability', 1, 2);

function custom_get_availability( $availability, $_product ) {
    //change text "In Stock' to 'SPECIAL ORDER'
    if ( $_product->is_in_stock() ) $availability['availability'] = __('AVAILABLE', 'woocommerce');

    //change text "Out of Stock' to 'SOLD OUT'
    if ( !$_product->is_in_stock() ) $availability['availability'] = __('SOLD OUT', 'woocommerce');
        return $availability;
    }

有没有办法从DataTable中检索比这更快的DataRow?

3 个答案:

答案 0 :(得分:1)

如果您确定只有一项条件符合条件,请使用FirstOrDefault代替Single。因此,您不会收集整个表格,只会收集您找到的第一个条目。

答案 1 :(得分:1)

您可以使用DataTable的选择方法。

var expression = "[MeteringPointId] = '" + MeteringPointId + "'";
DataRow[] result = MeteringPointsDataTable.Select(expression);

你也可以创建一个像

这样的表达式
var idList = new []{"id1", "id2", "id3", ...};
var expression = "[MeteringPointId] in " + string.Format("({0})", string.Join(",", idList.Select(i=> "'"+i+"'")));

类似的用法是here

希望有所帮助......

答案 2 :(得分:0)

你可以将整个表放在字典中:

        //At the start
        var meteringPoints = MeteringPointsDataTable.AsEnumerable().ToDictionary(r => r.Field<string>("MeteringPointId").ToString());

        //For each row of the text file:
        DataRow row;
        if (!meteringPoints.TryGetValue(MeteringPointId, out row))
        {
            row = MeteringPointsDataTable.NewRow();
            meteringPoints[MeteringPointId] = row;
        }