难道"的foreach"导致重复的LINQ执行? [英] Does "foreach" cause repeated Linq execution?

查看:151
本文介绍了难道"的foreach"导致重复的LINQ执行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经工作了首次与实体框架.NET中,并一直在写LINQ查询,以便从我的模型获取信息。我想从一开始良好的生活习惯进行编程,所以我一直在写这些查询的最佳方式进行研究,并得到了他们的成果。不幸的是,在浏览堆栈兑换,我似乎都遇到如何延迟/立即执行两个相互矛盾的解释与LINQ作品:

I've been working for the first time with the Entity Framework in .NET, and have been writing LINQ queries in order to get information from my model. I would like to program in good habits from the beginning, so I've been doing research on the best way to write these queries, and get their results. Unfortunately, in browsing Stack Exchange, I've seem to have come across two conflicting explanations in how deferred/immediate execution works with LINQ:


  • 一个foreach会导致在每次循环要执行的查询:

href=\"http://stackoverflow.com/questions/3575886/slow-foreach-on-a-linq-query-tolist-boosts-performance-immensely-why-is\">Slow的foreach()在LINQ查询 - 了ToList()提高性能极大 - 这是为什么,言外之意就是了ToList()的需求,以便立即评估查询被调用,如在foreach是评估重复数据源的查询,大大减慢了操作。

Demonstrated in question Slow foreach() on a LINQ query - ToList() boosts performance immensely - why is this? , the implication is that "ToList()" needs to be called in order to evaluate the query immediately, as the foreach is evaluating the query on the data source repeatedly, slowing down the operation considerably.

又如问题<一href=\"http://stackoverflow.com/questions/3738710/foreaching-through-grouped-linq-results-is-incredibly-slow-any-tips\">Foreaching通过分组LINQ结果是令人难以置信的速度慢,任何提示?,其中公认的答案也意味着称之为了ToList()的查询将提高性能。

Another example is the question Foreaching through grouped linq results is incredibly slow, any tips? , where the accepted answer also implies that calling "ToList()" on the query will improve performance.


  • 在foreach会导致执行一次的查询,并且是安全与LINQ
  • 来使用

体现在问题的foreach是否执行查询只有一次? ,言外之意就是在foreach导致建立1枚举,每一次都不会查询数据源。

Demonstrated in question Does foreach execute the query only once? , the implication is that the foreach causes one enumeration to be established, and will not query the datasource each time.

该网站的持续浏览已止跌回升,其中foreach循环中重复执行,是性能问题的罪魁祸首很多问题,很多其他的答案,说明一个foreach将相应地从一个数据源,抢单的查询其也就是说,两种解释似乎有有效性。如果了ToList()的假设是不正确(如目前大多数的答案是2013年6月5日下午1点51 EST似乎暗示),哪里这个误解从何而来?有这些解释是准确的一加一,是不是,还是有可能导致LINQ查询来评估不同情况下的不同?

Continued browsing of the site has turned up many questions where "repeated execution during a foreach loop" is the culprit of the performance concern, and plenty of other answers stating that a foreach will appropriately grab a single query from a datasource, which means that both explanations seem to have validity. If the "ToList()" hypothesis is incorrect (as most of the current answers as of 2013-06-05 1:51 PM EST seem to imply), where does this misconception come from? Is there one of these explanations that is accurate and one that isn't, or are there different circumstances that could cause a LINQ query to evaluate differently?

编辑:除了下面的接受的答案,我已经打开了以下问题在程序员是非常帮助我查询执行的理解,特别是陷阱,可能导致多个数据源中一个打循环,我认为将是其他人有兴趣在此问题有所帮助:<一href=\"http://programmers.stackexchange.com/questions/178218/for-vs-foreach-vs-linq\">http://programmers.stackexchange.com/questions/178218/for-vs-foreach-vs-linq

In addition to the accepted answer below, I've turned up the following question over on Programmers that very much helped my understanding of query execution, particularly the the pitfalls that could result in multiple datasource hits during a loop, which I think will be helpful for others interested in this question: http://programmers.stackexchange.com/questions/178218/for-vs-foreach-vs-linq

推荐答案

在一般的LINQ使用延迟执行。如果你使用像方法一() FirstOrDefault()查询被立即执行。当你做这样的事情;

In general LINQ uses deferred execution. If you use methods like First() and FirstOrDefault() the query is executed immediately. When you do something like;

foreach(string s in MyObjects.Select(x => x.AStringProp))

结果以流方式检索,这意味着一个接一个。每次迭代调用 MoveNext的突起被施加到​​下一个对象。如果你有一个其中,它会先应用过滤器,然后投影。

The results are retrieved in a streaming manner, meaning one by one. Each time the iterator calls MoveNext the projection is applied to the next object. If you were to have a Where it would first apply the filter, then the projection.

如果你做的东西等;

List<string> names = People.Select(x => x.Name).ToList();
foreach (string name in names)

然后,我相信这是一个浪费的操作。 了ToList()将强制执行的查询,枚举列表和应用 X =&GT; x.Name 投影。之后您将重新枚举列表。所以,除非你有一个很好的理由在列表(而不是IEnumerale)你只是在浪费CPU周期。数据

Then I believe this is a wasteful operation. ToList() will force the query to be executed, enumerating the People list and applying the x => x.Name projection. Afterwards you will enumerate the list again. So unless you have a good reason to have the data in a list (rather than IEnumerale) you're just wasting CPU cycles.

一般来说使用你正在使用一个foreach列举不会有比任何其它同类和实用的选项更差的性能集合LINQ查询。

Generally speaking using a LINQ query on the collection you're enumerating with a foreach will not have worse performance than any other similar and practical options.

另外值得注意的是鼓励人们实现LINQ提供程序,使常用的方法工作,因为他们在微软提供的供应商做的,但他们没有要求。如果我去写一个LINQ到HTML或LINQ到我的专有数据格式提供商就没有保证它以这种方式运行。也许该数据的性质将作出立即执行的唯一可行的选择。

Also it's worth noting that people implementing LINQ providers are encouraged to make the common methods work as they do in the Microsoft provided providers but they're not required to. If I were to go write a LINQ to HTML or LINQ to My Proprietary Data Format provider there would be no guarantee that it behaves in this manner. Perhaps the nature of the data would make immediate execution the only practical option.

此外,最后编辑;如果你有兴趣在这个乔恩斯基特的C#在深度是非常翔实和一个伟大的阅读。我的回答总结了本书(希望以合理的精度)的几页,但如果你想在LINQ在幕后是如何工作的详细信息,这是看的好地方。

Also, final edit; if you're interested in this Jon Skeet's C# In Depth is very informative and a great read. My answer summarizes a few pages of the book (hopefully with reasonable accuracy) but if you want more details on how LINQ works under the covers, it's a good place to look.

这篇关于难道&QUOT;的foreach&QUOT;导致重复的LINQ执行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆