Query Execution
The last action of the LINQ query operations is query execution. Even though the query expression is
defined and stored in a query variable when the query is created, the execution of the query does not
typically take place until iteration over the query variable begins. I’ll explain ‘‘typically’’ momentarily,
but I first want to discuss how a query is executed. As the query is iterated through, only the work
necessary to bring back the current result is done. In other words, the entire query is not returned. Each
iteration of the query returns the next item in the result.
It has been said previously that neither the query expression itself nor the variable contains query results.
That is because the query is executed as you iterate through the variable. Here’s the string array
example from Chapter 1:
string [] firstnames = { "Scott", "Steve", "Ken", "Joe", "John",
"Alex", "Chuck", "Sarah"};
IEnumerable<string> val = from fn in firstnames
where fn.StartsWith("S")
select fn;
foreach (string name in val)
{
Console.WriteLine(name);
}
The first ‘‘action’’ defines the data source. The second ‘‘action’’ defines the query and assigns it to a
variable. The last ‘‘action,’’ the foreach loop (For Each in Visual Basic), executes the query by iterating
over the variable val in the foreach loop.
How does this work? Take a look at the foreach loop:
Foreach (string name in val)
Console.WriteLine(name);
The first time the foreach statement is executed, the first call to the MoveNext() method causes
three things:
1. The query is translated to SQL.
2. The query is executed.
3. The first row is fetched from the underlying DataReader.
For each iteration thereafter, the MoveNext() method is called, grabbing the next row from the underlying
DataReader, hydrating (queuing) the next object.
The best way to understand this is to see it in action. Take a look at Figure 3-1, which shows the preceding
example during code execution. I have stopped the execution of the code on the foreach statement on
the first iteration.
What you want to look at is the Watch window below the code where I have the query variable being
watched. Notice the value of the name-value pair named Results View. It states, ‘‘Expanding the Results
View will enumerate the IEnumerable.’’ This tells you that the query has not been executed, that even
the internal results have not been iterated through, and that expanding the node will be equivalent to
stepping through the foreach loop until all the results are received.
So what does typically mean? There are two types of query execution: deferred and immediate. In most
cases you want to use deferred; however, there are cases when immediate execution is necessary.