I've been experimenting with Linq to see what it can do - and I'm really loving it so far :)
I wrote some queries for an algorithm, but I didn't get the results I expected... the Enumeration always returned empty:
case #1
List<some_object> next = new List<some_object>();
some_object current = null;
var valid_next_links =
from candidate in next
where (current.toTime + TimeSpan.FromMinutes(5) <= candidate.fromTime)
orderby candidate.fromTime
select candidate;
current = something;
next = some_list_of_things;
foreach (some_object l in valid_next_links)
{
//do stuff with l
}
I changed the query declaration to be inline like this, and it worked fine:
case #2
foreach (some_object l in
(from candidate in next
where (current.toTime + TimeSpan.FromMinutes(5) <= candidate.fromTime)
orderby candidate.fromTime
select candidate))
{
//do stuff with l
}
Does anybody know why it doesn't work in case #1 ? The way I understood it, the query wasn't evaluated when you declared it, so I don't see how there is a difference.
Benefits of Deferred Execution –It avoids unnecessary query execution and hence improves performance. Query construction and Query execution are decoupled, so we can create the LINQ query in several steps. A deferred execution query is reevaluated when you re-enumerate – hence we always get the latest data.
LINQ queries are always executed when the query variable is iterated over, not when the query variable is created. This is called deferred execution. You can also force a query to execute immediately, which is useful for caching query results.
The basic difference between a Deferred execution vs Immediate execution is that Deferred execution of queries produce a sequence of values, whereas Immediate execution of queries return a singleton value and is executed immediately.
Deferred execution means that the evaluation of an expression is delayed until its realized value is actually required. It greatly improves performance by avoiding unnecessary execution.
Changes to current
will be captured, but the query already knows the value of next
. Adding extra items to the existing list will make them show up in the query, but changing the value of the variable to refer to a different list entirely won't have any effect. Basically, if you mentally expand the query from a query expression into a "normal" form, any variable present in a lambda expression will be captured as a variable, but any variable present directly as an argument will be evaluated immediately. That will only capture the reference value of the variable, not the items present in the list, but it still means changing the variable value itself won't be seen. Your first query expands to:
var valid_next_links = next
.Where(candidate => (current.toTime + TimeSpan.FromMinutes(5) <= candidate.fromTime))
.OrderBy(candidate => candidate.fromTime);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With