优化使用AsEnumerable和SingleOrDefault的查询

本文关键字:SingleOrDefault 查询 AsEnumerable 优化 | 更新日期: 2023-09-27 18:26:26

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

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

我这样做的方法是将包含数据库中数据的完整数据库表检索到内存中,然后只更新该信息,最后通过调用datatables update函数保存更改。它工作得很好,只是找到MeteringPointId的行很慢:

DataRow row = MeteringPointsDataTable.NewRow();
// this is called for each line in the text file to find the corresponding MeteringPointId. It can be 300.000 times.
row = MeteringPointsDataTable.AsEnumerable().SingleOrDefault(r => r.Field<string>("MeteringPointId").ToString() == MeteringPointId);

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

优化使用AsEnumerable和SingleOrDefault的查询

如果您确定只有一项满足条件,则使用FirstOrDefault而不是Single。因此,您不会收集整张表,只会收集您找到的第一个条目。

您可以使用选择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+"'")));

类似的用法在这里

希望能有所帮助。。

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

        //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;
        }