【问题标题】:Linq to objects - boondoggle?Linq to objects - boondoggle?
【发布时间】:2018-03-03 10:54:09
【问题描述】:

我认为 LINQ to objects 是不同执行连接数据的好方法。实际上,这是一种糟糕的做事方式......

这就是我们所拥有的,在 a,b,c,d 中相应地有几条、几百条、3K 和 3.5K 条记录

IEnumerable<MyModel> data =
    (from a in AList
     from b in BList.Where(r => r.AId == a.Id)
     from c in CList.Where(r => r.BId == b.Id)
     from d in DList.Where(r => r.SomeId == myId && r.Some2Id == c.Some2Id)
 //  . . . . . . 

难道 LINQ 不应该做得很好吗? 实际上,following 的工作速度要快得多,实际上快 60 倍

var dTemp = DList.Where(r => r.SomeId == myId).ToList();
var cTemp = CList.Where(c => dTemp.Any(d => d.Some2Id == c.Some2Id)).ToList();

IEnumerable<MyModel> data =
    (from a in AList
     from b in BList.Where(r => r.AId == a.Id)
     from c in cTemp.Where(r => r.BId == b.Id)
 //  . . . . . .

然后我遇到了this article

问:有没有办法在不放弃单个 LINQ 的情况下改进此查询?

或者这是否意味着如果性能受到威胁,需要避免使用连接形式的 LINQ to 对象并用一些顺序调用来代替?

【问题讨论】:

  • 您似乎正在尝试内联 abc。您是否尝试过使用 Join 函数而不是 where 的函数?
  • 考虑不那么激进地悲观您的 LINQ。 “我是万无一失的,所以框架必须被打破”通常不是最好的起点。
  • @EdPlunkett 请。我从不说它坏了。但看起来,由于需要优化器,它并不能很好地完成这项工作
  • @Reddog 是的,现在我们正在对此进行优化。那只是不好的做法。在某些情况下,它的工作原理相同,但 join 更快

标签: c# .net linq linq-to-objects


【解决方案1】:

让我们分析一下差异。

第一个查询:您正在对BList 执行一个过滤器,在CList 上执行一个过滤器,在DList 上执行两个过滤器,所有这些都以延迟执行的方式进行。然后您使用一种连接。
第二个查询:您对 DList 执行一个静态过滤器并评估它,另一个基于 DList 的静态过滤器在 CList 上执行并评估它然后是 AListBList 上的延迟执行过滤器。

第二个查询更快,因为:

  • DList 没有被查看无用值(由于之前的过滤器)
  • CList 由于以前的过滤器而仅包含有用的值

无论如何,这两个查询都是错误的。多个from 基本上是一个cross-joinas explained here。正如@Reddog 评论的那样,最好的方法是实际使用Join

var data = from a in AList
           join b in BList on a.Id equals b.AId
           join c in CList on b.Id equals c.BId
           join d in DList on c.Some2Id equals d.Some2Id
           where d.SomeId == someId;

【讨论】:

  • 你是对的。在某些情况下from-fromfrom-join 的工作方式相同。对于小型数据集,我们从来没有遇到过问题。但是这个客户有一个独特的设置,他们在cd 有很大的[巨大] 设置,而且效果不太好。即便如此,-140 毫秒也没那么糟糕,但在这种设置下,它会反复运行。所以 140x20... 现在是 2 毫秒。 2x20 - 非常不同的结果。我们之前会对其进行调整,但我们针对替换缓存数据的 SQL 调用进行了基准测试,并且效果很好。所以,没有人注意一点 LINQ 的事实。谢谢
猜你喜欢
  • 1970-01-01
  • 2011-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多