Database Reference
In-Depth Information
How It Works
We start by creating a Club and three Events. In the query, we grab all of the events at clubs in New York, group them
by club, and find the first one in date order. Note how the FirstOrDefault() LINQ extension method is cleverly
embedded in the Select, or projection, operation. However, the events variable holds just the expression. It hasn't
executed anything on the database yet.
Next we leverage the Include() method to eagerly load information from the related Club entity object using the
variable, events, from the first LINQ query as the input for the second LINQ query. This is an example of composing
LINQ queries—breaking a more complex LINQ query into a series of smaller queries, where the variable of the
preceding query is in the source of the query.
Note how we use the First() method to select just the first Event instance. Doing so returns a type of
Event, as opposed to a collection of Event objects. Entity Framework 6 contains a new static class entitled
IQueryableExtensions, which exposes an Include() method prototype that accepts either a string-based or strongly
typed query path parameter. The IQueryableExtensions class replaces the DbExtensions class from EF 4 and EF 5.
Many developers find the Include() method somewhat confusing. In some cases, IntelliSense will not show it as
available (because of the type of the expression). At other times, it will be silently ignored at runtime. Surprisingly, the
compiler rarely complains unless it cannot determine the resulting type. The problems usually show up at runtime
when they can be a more difficult fix. Here are some simple rules to follow when using Include() :
The Include() method is an extension method on type IQueryable<T> .
1.
2. Include() applies only to the final query results. When Include() is applied to a
subquery, join, or nested from clause, it is ignored when the command tree is generated.
Under the hood, Entity Framework translates your LINQ-to-Entities query into a construct
called a command tree , which is then handed to the database provider to construct a SQL
query for the target database.
3. Include() can be applied only to results that are entities. If the expression projects results
that are not entities, Include() will be ignored.
The query cannot change the type of the results between the Include() and the outermost
operation. A group by clause, for example, changes the type of the results.
4.
The query path used in the Include() expression must start at a navigation property
on the type returned from the outermost operation. The query path cannot start at an
arbitrary point.
5.
Let's see how these rules apply to the code in Listing 5-17. The query groups the events by the sponsoring club.
The group by operator changes the result type from Event to a grouping result. Here Rule 4 says that we need to
invoke the Include() method after the group by clause has changed the type. We do this by invoking Include()
at the very end. If we applied the Include() method earlier as in from ev in context.Events.Include() , the
Include() method would have been silently dropped from the command tree and never applied.
5-8. Deferred Loading of Related Entities
Problem
You have an instance of an entity, and you want to defer the loading of two or more related entities in a single query.
Especially important here is how we use the Load() method to avoid requerying the same entity twice. Additionally,
you want to implement the Code-First approach for Entity Framework 6 to manage data access.
Solution
Suppose that you have a model like the one in Figure 5-23 .
 
Search WWH ::




Custom Search