如何最小化 linq 查询并提高性能

本文关键字:高性能 查询 linq 最小化 | 更新日期: 2023-09-27 18:36:55

var Table = new List();
var partlist = Table
    .AsEnumerable()
    .Where(row =>
    {
        if (!string.IsNullOrEmpty(row.Field<string>("Column1")) &&
            row.Field<string>("Column1").Equals(variableName1) &&
            !string.IsNullOrEmpty(row.Field<string>("Column2")) &&
            row.Field<string>("Column2").Equals(variableName2))
            return true;
        return false;
    })
    .Select(row =>
    {
        return new
        {
            PartNumber = row.Field<string>("HardwareType"),
            Number = row.Field<string>("HardwareSerialNo")
        };
    })
    .Distinct();
var distinctParts =
    partlist
        .Select(part => { return part.PartNumber; })
        .Distinct();
foreach (var distinctPart in distinctParts)
{
    var list = partlist.Where(part =>
    {
        if (part.PartNumber.Equals(distinctPart))
            return true;
        return false;
    })
    .Select(part => { return part.Number; })
    .Distinct();
    int quantity = list.Count();
    hwList[distinctPart] = quantity;
}

上面的代码工作正常,但执行时间很长。有没有办法最小化代码并提高性能。请帮帮我

如何最小化 linq 查询并提高性能

这里的问题是您没有使用正确的数据类型。对于distinctParts中的每个条目,它都需要迭代partlist。这是一个巨大的问题,因为partlist定义查询而不是查询的结果。换句话说,对于 foreach 循环的每次迭代,都会执行 partlist 查询,并执行您为其定义的所有代码:

  1. 从行中提取数据
  2. 创建匿名类型的新实例
  3. 删除重复的条目。

这是由于 LINQ 查询的延迟性质造成的。

我会通过从partlist中提取直接包含所需数据的字典来解决这个问题。这将只执行一次partlist查询:

var parts = partlist.GroupBy(x => x.PartNumber)
                    .ToDictionary(x => x.Key,
                                  x => x.Select(y => y.Number)
                                        .Distinct().Count()));
foreach (var kvp in parts)
    hwList[kvp.Key] = kvp.Value;

请注意:我还删除了对此distinctParts的需要。
这应该快很多。

您可以抽象出一些过滤,但除此之外,我看不到可以增强的地方:

function bool IsMatch(row, column, match)
{
    var value = row.Field<string>(column);
    return !string.IsNullOrEmpty(value) && value.Equals(match);
}

这只会真正使它更具可读性:

.Where(row => {
    return IsMatch(row, "Column1", variableName1) && 
           IsMatch(row, "Column2", variableName2);
 })

您的匿名对象也有类似的事情。如果你创建一个轻量级的小类,你可以将实现抽象到构造函数:

public class PartModel
{
    public PartModel(TableRow row)
    {
        PartNumber = row.Field<string>("HardwareType");
        Number = row.Field<string> ("HardwareSerialNo");
    }
    public string PartNumber { get; set; }
    public string Number { get; set; }
}

这简化了:

.Select(row => { return new PartModel(row) }; })