C# foreach加速方法的替代方案

C# foreach加速方法的替代方案,c#,linq,C#,Linq,我正在逐步完成这段代码,这个方法需要一段时间来迭代20K产品。 是否有一种替代foreach循环的方法来加速这个过程?这可以用Linq来完成吗 public IEnumerable<IProduct> ReturnOnlyRequestedSkus(IEnumerable<IProduct> products, IEnumerable<string> requestedSkus) { var productList = new List<IPro

我正在逐步完成这段代码,这个方法需要一段时间来迭代20K产品。 是否有一种替代foreach循环的方法来加速这个过程?这可以用Linq来完成吗

public IEnumerable<IProduct> ReturnOnlyRequestedSkus(IEnumerable<IProduct> products, IEnumerable<string> requestedSkus)
{
    var productList = new List<IProduct>();

    var allowedProducts = from sku in requestedSkus
                          join product in products
                          on sku.ToUpper() equals product.Sku.ToUpper()
                          select product;

    foreach (var product in allowedProducts)
    {
        if (product.ItemType.Equals("Kit", StringComparison.OrdinalIgnoreCase) 
                 && product.KitIncludes != null)
        {
            var skusInKit = product.KitIncludes.Select(x => x.Sku);
            var skusInProducts = products.Select(x => x.Sku);

            if (skusInProducts.ContainsAll(skusInKit))
            {
                productList.Add(product);
            }

        }
    }

    return productList;
}

假设您实际上试图在这里查询数据库,您没有说,但大多数处理20K+产品的应用程序往往不会将它们保存在内存中,而是使用IQueryable,将其转换为一个大型LINQ表达式,并将其传递给数据库进行计算,而不是将其全部读取到内存中进行客户端查询和列表构建

public IQueryable<IProduct> ReturnOnlyRequestedSkus(IQueryable<IProduct> 
products, IEnumerable<string> requestedSkus)
{
  return products
    .Where(p => requestedSkus.Any(sku => String.Equals(p.Sku, sku, StringComparison.OrdinalIgnoreCase &&
       p.ItemType.Equals("Kit", StringComparison.OrdinalIgnoreCase) && 
       p.KitIncludes != null &&
       ...
       ;
}
这样我就可以减少你穿过电线的次数;ii数据库本身可以优化查询;你的结果会被懒散地评估,所以如果有人打电话给你。首先是他们,或者。数一数,它不会把他们全部取出来


但最后一部分是什么?套件中的所有零件都是产品本身?这不是您应该在数据库级别使用约束来确保的吗

你认为LINQ在引擎盖下做什么?担心foreach vs LINQ是一种转移注意力的方法,看看你的代码中的其他低效率问题,你能提供更多信息吗?没有足够的信息告诉我们如何最好地帮助您/或者您可以在另一个线程中运行代码并通过回调或事件返回结果。我认为可能效率低下的一个语句是:var skusInProducts=products.Selectx=>x.Sku;它是在循环的每次迭代中完成的,但它不是必需的,因为产品集合不会更改。记住allowedProducts是一个对象,它实际上不包含数据,但为延迟执行查询提供了一个接口。调用resultset上的ToList以强制执行所有操作。然后检查性能问题是否如您所认为的是在迭代循环期间,还是实际上是DB性能问题。OP是否有任何迹象表明这是LINQ to SQL?这可能只是纯LINQ,因为有明显的inefficiencies@maccettura这个问题明确地将参数显示为IEnumerable,而不是IQueryable,因此我们实际上确切地知道这不是某种DB查询操作。@这是一个很好的观点。所以这个答案根本不适用then@maccettura,@servy很好,它应该是可查询的-产品目录通常不会存在于内存中-但我们不应该假设-我在答案中添加了一个前言。