Databases Reference
In-Depth Information
In this code snippet, a familiar LINQ query is compiled with the help of the Compile
method of the CompiledQuery class and stored in a static field called customersByCity .
The compiled query itself is a lambda expression, which takes an object context as its first
parameter, a city as its second, and returns an IQueryable of Customer. Typically, a
compiled query like this is stored in a static field of a class that performs the data access
and can benefit from compiled queries.
The data access code based on compiled queries is similar to the traditional LINQ queries
in that it still needs to create an ObjectContext , like NorthwindEntities in this ongoing
example. However, instead of using LINQ queries directly, it calls the Invoke method of
one or more of the compiled query objects as shown here:
using (NorthwindEntities context = new NorthwindEntities())
{
var customers = customersByCity.Invoke (context, “London”);
foreach (Customer c in customers)
Console.WriteLine(c.ContactName);
}
The work required to translate the compiled LINQ query into SQL statement is performed
the first time the compiled query is executed. So the program will still take the perfor-
mance hit the first time the compiled query is executed in an AppDomain ; however, all
subsequent executions of the compiled query will take advantage of the information
cached by the Entity Framework the first time and run faster.
Query composition defeats the caching logic the Entity Framework uses and negates the
benefits of query compilation. To keep the benefits of query compilation, you need to
compile the entire query and avoid modifying it in any way. As an example, consider the
code that follows, which adds an orderby clause to the same compiled query used in the
previous sample:
var customers = customersByCity.Invoke(context, “London”);
customers = from c in customers
orderby c.ContactName
select c;
foreach (Customer c in customers)
Console.WriteLine(c.ContactName);
The actual LINQ query executed in this sample is different from the compiled query and
cannot take advantage of the Entity Framework caching logic.
To avoid doing this by accident, you can change the compiled query to return an
IEnumerable instead of an IQueryable .
static Func<NorthwindEntities, string, IEnumerable <Customer>>
customersByCity =
CompiledQuery.Compile<NorthwindEntities, string, IEnumerable <Customer>>(
(context, city) =>
from c in context.Customers
Search WWH ::




Custom Search