简体   繁体   English

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

[英]How to minimize linq queries and increase the performance

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

The above code is working fine but its taking very long to execute. 上面的代码工作正常,但执行时间很长。 Is there any way to minimize the code and increase the performance. 有没有办法最小化代码并提高性能。 Please help me out 请帮帮我

The problem here is that you are not using the correct data type. 这里的问题是您没有使用正确的数据类型。 For every entry in distinctParts it needs to iterate partlist . 对于distinctParts每个条目,它需要迭代partlist And that is a huge problem, because partlist defines a query and not the result of a query. 这是一个很大的问题,因为partlist定义了一个查询,而不是查询结果 In other words, for each iteration of the foreach loop, the partlist query is executed, executing all the code you defined for it: 换句话说,对于foreach循环的每次迭代,都会执行partlist 查询 ,执行您为其定义的所有代码:

  1. Extracting the data from the rows 从行中提取数据
  2. Creating new instances of the anonymous type 创建匿名类型的新实例
  3. Removing the duplicate entries. 删除重复的条目。

This is due to the deferred nature of LINQ queries. 这是由于LINQ查询的延迟性质。

I would go about this problem by extracting a dictionary from partlist that directly contains the data you need. 我会通过从partlist中提取直接包含所需数据的字典来解决这个问题。 This would execute the partlist query exactly once: 这将只执行一次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;

Please note: I additionally removed the need for distinctParts with this. 请注意:我另外删除了对distinctParts的需求。
This should be a lot faster. 这应该快得多。

You could abstract out some of your filtering but otherwise I don't see places to enhance: 您可以抽象出一些过滤但我看不到要加强的地方:

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

which only really makes it more readable: 这只会让它更具可读性:

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

similar thing goes with your anonymous object. 类似的事情与你的匿名对象有关。 If you create a light little class you can abstract the implementation to the constructor: 如果你创建一个简单的小类,你可以将实现抽象到构造函数:

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

which simplifies that to: 这简化了:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM