I would like to cite Charlie Calvert, he has clearly described deferred execution.
Consider this simple LINQ to SQL query:
var query = from customer in db.Customers
where customer.City == "Paris"
select customer;
It is easy to assume that these few lines of code execute a query against a database. In fact, they do not. This code merely captures the idea of the query in a data structure called an expression tree. The tree contains information about the table you want to query, the question you want to ask of the table, and the result you want to return. It does not, however, actually execute the query!
In LINQ, execution of a query is usually deferred until the moment when you actually request the data. For instance, the following code would cause the query to execute:
foreach (var Customer in query) // Query executes here
{
Console.WriteLine(Customer.CompanyName);
}
Query expressions often do not cause code to be executed. They only define the question you want to ask. If this were not the case, then it would be difficult or impossible for LINQ to break queries down into a relational algebra which makes composability possible, and which allows developers who care about such things to optimize their code. Deferred execution makes it possible for you to compose quite complex queries from various components without expending the clock cycles necessary to actually query the data. Or at least the data will not be queried until it is absolutely necessary.
Let’s make a slight change to the query shown above:
var query = (from customer in db.Customers
where customer.City == "Paris"
select customer).Count(); // Query executes here
This time the query will be run when the execution point moves past it. The code executes when you call
Count(), as it would when you call any of the other operators that must iterate over the result of a query in order to return a value that is not
IEnumerable<T> or
IQueryable<T>. The
ToList() operator the query code to execute immediately because it returns a
List<T> instead of
IQueryable<T>. Consider the following code:
public void SimpleQuery01()
{
db.Log = Console.Out;
// Query executes here because it returns a List;
List list = (from customer in db.Customers
where customer.City == "Paris"
select customer).ToList();
foreach (var Customer in list)
{
Console.WriteLine(Customer.CompanyName);
}
}
One of the last things the LINQ to SQL provider does before executing a query is to create the SQL it will send across the wire. This fact gives us a clue we can use when trying to determine the exact moment when a query executes.
Full article:
blogs.msdn.com/b/charlie/archive/2007/12/09/deferred-execution.aspx
No comments:
Post a Comment