Given a very basic LINQ that is returned to a MVC view, at what exact point does the deferred execution fire?
In the controller:
public ActionResult Index()
{
var model = _fooService.GetAll();
return View(model);
}
In the model:
@foreach (var item in Model) {
<tr>
<td>@item.Bar</td>
</tr>
}
The query is not executed when we call _fooService.GetAll() of course, but is deferred to some later point – but at which exact point is it executed?
- The
return View(model);statement in the controller (doesn’t look like it)? - The
@foreach (var item in Model)line in the view? - The first time the
@item.Barline in the view is hit? - Something else that occurs in between
return View(model);and the view being rendered?
MSDN documentation addresses this question under the deferred query execution section (emphasis mine).
That narrows down the answer to options 2 and 3.
foreachis just syntactic sugar, underneath the compiler re-writes that as a while loop. There’s a pretty thorough explanation of what happens here. Basically your loop will end up looking something like thisEnumerator is advanced before it reaches your code inside the loop, so slightly before you get to
@item.Bar. That only leaves option 2, the@foreach (var item in Model)line (though technically that line doesn’t exist after the compiler is done with your code).I’m not sue if the query will execute on the call to
GetEnumerator()or on the first call toe.MoveNext().As @pst points out in the comments, there are other ways to trigger execution of a query, such as by calling
ToList, and it may not internally use aforeachloop. MSDN documentation sort of addresses this here:My understanding of that is an attempt to enumerate the expression will cause it to execute (be it through a
foreachor some other way). How exactly that happens will depend on the implementation of the provider.