¿Cuándo se ejecuta realmente la consulta LINQ?

Suppose we have the following LINQ query:

var query =
    from    c in Customers
    where   c.Country == "Italy"
    orderby c.Name
    select  new { c.Name, c.City };

Compiler will convert it like this:

IEnumerable<Customer> query =
        Customers
        .Where( c => c.Country == "Italy" );
        .OrderBy( c => c.Name )
        .Select( c => new { c.Name, c.City } );

Then I coud use the query like this:

foreach ( var name_city_pair in query ) ...

Las preguntas son:

  • It seems the data specified by the pregunta is already queried out when I use the foreach loop. So when is this query action take place? Is it when I define the LINQ query object of IEnumerable<Customer> ?

  • If the data number is too large, is there any late query mechanism? (I am not sure about the right word to describe this, but I hope you get me.)

preguntado el 25 de agosto de 12 a las 02:08

I think you may have a few syntax error above. You are selecting an Anonymous type, then saying the selected object is of type Customer, then iterating over the query like it an IEnumerable<string>. -

Thanks for your reminding. Corrected now. -

3 Respuestas

LINQ uses deferred execution where possible. In your example the query is only executed when you iterate over the results.

The methods that start with To (Tales como ToList) cause the query to be executed immediately. Also some methods that return a single value such as Count cause the query to be executed immediately.

Respondido 25 ago 12, 02:08

Generally speaking LINQ tries to be as lazy as possible. For example you'd expect it to look something like this behind the scenes:

foreach ( string name in query ) ...
//Roughly translates into
while (query.MoveNext())
{
    string name = query.Current;
    ...
}

Which only gets the results as it needs them, one by one. This 'lazy'/'streamed' thinking works through the whole query - Select calls OrderBy as needed, which calls Where as needed which calls the Collection as needed.

The one oddity is the 'OrderBy' which, for implementation reasons, might retrieve all the needed results before ordering them, then stream the result. This retrieval will occur when it's first called.

Respondido 25 ago 12, 02:08

Does this assume Linq-To-Objects? And if so, would your answer be any different if it were Linq-To-Sql or Entity Framework? - brad rem

The specifics assume LinqToObjects, though all implementations should try to be lazy IIRC. MongoDB for example would compile & send query to the DB at the first call, and return a 'MongoCursor' which will handle the getting of the document for every iteration IIRC. [It may batch documents 4MB a time IIRC]. - NPSF3000

The query doesn't execute before the foreach. Each iteration in your foreach loop will return one result from your query.

Never is there a fully materialized result set of data, so it can't be too large either.

A LINQ query defers execution. As you iterate it will 'slide' forward over your data applying the predicates and projections you specified.

Respondido 25 ago 12, 02:08

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.