简体   繁体   English

IEnumerable vs ToList直接在视图中进行迭代

[英]IEnumerable vs ToList while directly iterating in view

If I only have to use that result one time ie in iterating and displaying in view. 如果我只需要使用该结果一次,即在视图中迭代和显示。 I generally do 1st one, is it wiser? 我通常会做第一个,是否更明智?

IEnumerable<model> result = _someService.GetValues();
return View(result);

OR 要么

IList<model> result = _someService.GetValues().ToList();
return View(result);

I checked in profiler and db is queried only once for that data using EF6. 我检入了事件探查器,并且使用EF6仅对该数据查询一次db。

To clear its a plain SELECT and both has data and there is no adjacent list to kick in lazy loading. 为了清除它的纯SELECT,并且两者都具有数据,并且没有相邻列表可用于延迟加载。

Note: I know IEnumerable has one method GetEnumerator which executes everytime its called it executes for data whereas ToList() executes only once. 注意:我知道IEnumerable有一个方法GetEnumerator,它在每次调用它对数据执行时都会执行,而ToList()仅执行一次。

See Programmers.SE: Why should I use List<T> over IEnumerable<T> ? 请参阅Programmers.SE:为什么我应该在IEnumerable<T>使用List<T> IEnumerable<T> :

There are times when doing a ToList() on your linq queries can be important to ensure your queries execute at the time and in the order that you expect them to. 有时候,对linq查询执行ToList()对于确保查询按时间和顺序执行很重要。

This is exactly the case here. 这就是这里的情况。

If _someService.GetValues() returns an IEnumerable<model> which is an Entity Framework query through deferred execution, calling ToList() in your controller will execute the query there: in your controller, where you can handle the exceptions that may occur. 如果_someService.GetValues()返回IEnumerable<model>这是通过延迟执行进行的实体框架查询ToList() ,则在控制器中调用ToList()将在该位置执行查询:在控制器中,您可以在其中处理可能发生的异常。 For example a query timeout. 例如查询超时。

If you don't call .ToList() , that same exception will be thrown instead at @foreach (var item in Model) in your view. 如果不调用.ToList() ,则将在视图中的@foreach (var item in Model)中的@foreach (var item in Model)上抛出相同的异常。 You don't want that. 你不要那样

Also, if you use lazy loading, the context will be disposed by the time the query result end up in your view and throw an exception again, so in that case you'll have to materialize the query results in your controller by calling .ToList() . 另外,如果您使用延迟加载,则上下文将在查询结果最终出现在视图中时.ToList() ,并再次引发异常,因此在这种情况下,您将必须通过调用.ToList()在控制器中具体化查询结果。 .ToList()


People get all high up in a tree when it comes to IEnumerable<T> versus IList<T> . 当涉及到IEnumerable<T>IList<T>时,人们全都高高在上。 They are generally parroting each other from some general advice (found here, amongst others ), but they do not understand that that advice is for API design . 他们通常会从一些一般性建议中相互模仿 (在此处找到其他建议),但是他们不明白该建议是针对API设计的 You are not designing an API, you are implementing an application with very specific requirements: the view may never throw an exception. 您不是在设计API,而是在实现具有非常特定要求的应用程序:视图可能永远不会引发异常。 In order to fulfill that requirement, you must execute your queries in your controller, hence call .ToList() there. 为了满足该要求,您必须在控制器中执行查询,因此在此调用.ToList()

The user asking the question linked above is right in the comment they posted : 用户问上面链接的问题,就在他们发表的评论中

all queries should be executed so that the model is done and loaded ready for the view. 应该执行所有查询,以便完成模型并为视图准备加载。 Ie the view should receive everything and not be querying the database. 即视图应该接收所有内容,而不是查询数据库。

Razor rendering your model to your view may not have any side-effects. 剃刀将模型渲染到视图可能没有任何副作用。 Executing a query is a side-effect, so that may not happen while rendering your view. 执行查询是一个副作用,因此在呈现视图时可能不会发生。

Even when calling .ToList() in your controller, your @model directive in the view can and should still be of IEnumerable<T> though! 即使在控制器中调用.ToList()时,视图中的@model指令也可以而且应该仍为IEnumerable<T>

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

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