【问题标题】:IEnumerable vs ToList while directly iterating in viewIEnumerable vs ToList 直接在视图中迭代
【发布时间】:2015-12-16 09:15:52
【问题描述】:

如果我只需要使用该结果一次,即在视图中进行迭代和显示。我一般做第一个,是不是比较明智​​?

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

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

我签入了分析器,并且使用 EF6 仅针对该数据查询 db 一次。

清除它是一个普通的 SELECT 并且两者都有数据并且没有相邻的列表可以启动延迟加载。

注意:我知道 IEnumerable 有一个 GetEnumerator 方法,它在每次调用它时都会执行,它会执行数据,而 ToList() 只执行一次。

【问题讨论】:

  • 如果不知道GetValues 内部发生了什么,几乎不可能回答您的问题。
  • @AndyKorneyev 它的一组相同的值符合模型
  • 为什么这是负面的,问题似乎很清楚?

标签: c# entity-framework


【解决方案1】:

Programmers.SE: Why should I use List&lt;T&gt; over IEnumerable&lt;T&gt;?:

有时对 linq 查询执行 ToList() 对确保查询按您期望的时间和顺序执行很重要。

这里正是如此。

如果_someService.GetValues() 返回一个IEnumerable&lt;model&gt;,这是一个通过延迟执行的实体框架查询,则在您的控制器中调用ToList() 将在那里执行查询:在您的控制器中,您可以在其中处理可能发生的异常。例如查询超时。

如果您不调用.ToList(),则会在您的视图中在@foreach (var item in Model) 处引发相同的异常。你不想这样。

另外,如果您使用延迟加载,上下文将在查询结果最终出现在您的视图中并再次引发异常时被释放,因此在这种情况下您将必须具体化通过调用.ToList(),查询结果在您的控制器中。


当谈到IEnumerable&lt;T&gt;IList&lt;T&gt; 时,人们会一头雾水。他们通常互相模仿一些一般性建议(找到here, amongst others),但他们不明白该建议是针对API 设计。您不是在设计 API,而是在实现具有非常特定要求的应用程序:视图可能永远不会抛出异常。为了满足这个要求,你必须在你的控制器中执行你的查询,因此在那里调用.ToList()

提出上述问题的用户就在the comment they posted

应执行所有查询,以便模型完成并为视图加载做好准备。 IE。视图应该接收所有内容,而不是查询数据库。

Razor 将您的模型渲染到您的视图可能没有任何副作用。执行查询是一种副作用,因此在渲染视图时可能不会发生这种情况。

即使在您的控制器中调用.ToList(),您在视图中的@model 指令仍然可以而且应该仍然是IEnumerable&lt;T&gt;

【讨论】:

  • 谢谢,但我正在考虑更多关于我们确实有数据的情况,没有其他相邻字段用于延迟加载
  • 你这是什么意思?您无法提前知道何时会发生异常,即使您“有数据”也会发生异常。
  • 你能告诉我在 List 中不会出现异常以及在迭代时如何在 IEnum 中出现异常吗?注意:我礼貌地问你这个问题
  • 我想我在回答中解释了这一点,但请参阅希望使其更清晰的编辑。我并不是说.ToList() 防止异常,它只是让它出现在那个可预测的位置,而不是在你的视野中。
  • 即使在您提供的链接上“长话短说,只要您只需要迭代就使用 IEnumerable,当您需要直接索引并需要动态大小的数组时使用 IList”这个或多或少的答案,但是是例外必须处理,我通常不会:-(
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-08-22
  • 1970-01-01
  • 1970-01-01
  • 2015-05-01
  • 1970-01-01
  • 2017-11-04
  • 1970-01-01
相关资源
最近更新 更多