Heads up! To view this whole video, sign in with your Courses account or enroll in your free 7-day trial. Sign In Enroll
Preview
Start a free Courses trial
to watch this video
So far in this course, we've eagerly loaded related entities using the `Include` method. Let's take a look at the other two options—lazy and explicit loading to see how they compare.
Follow Along
To follow along commiting your changes to this course, you'll need to fork the dotnet-comic-book-gallery-model repo. Then you can clone, commit, and push your changes to your fork like this:
git clone <your-fork>
cd dotnet-comic-book-gallery-model
git checkout tags/v4.4 -b loading-related-entities
Additional Learning
When retrieving entities it's common to
need to load entities that are related to
0:00
the main entity that you're interested in.
0:04
For instance, in the previous section when
we executed a query to retrieve a list
0:06
of comic books, we also needed
to load the related artist and
0:11
role entities for
each comic book in the list.
0:15
EF supports three methods for
loading related entities.
0:18
When eagerly loading related entities,
0:23
you can write a single query that
not only retrieves the data for
0:25
the main entity, but also the data for
the related entities.
0:29
The include method is used to tell
EF which related entities to load.
0:33
With lazy loading the related entities
0:38
are not loaded until their
navigation properties are accessed.
0:40
The process of lazily loading related
entities is automatically handled by EF so
0:45
it can seem like magic the first
time that you see it in action.
0:51
As an alternative to lazy loading
0:55
you can also explicitly load related
entities using the load method.
0:57
So far in this course,
1:02
we've eagerly loaded related
entities using the include method.
1:04
Let's take a look at the other
two options, lazy and
1:08
explicit loading to see how they compare.
1:11
If you're following along,
1:14
let's start with removing
the changes from the previous video.
1:16
Here's the original query that we were
using to retrieve the list of comic books.
1:31
These three include method calls
tell EF to eagerly load the series,
1:36
comic book artist,
artist and role entities.
1:41
Let's switch to using lazy loading.
1:45
First, let's comment out
these three lines of code.
1:48
Second, we need to update
the comic book and
1:52
comic book artist entity navigation
properties to be virtual.
1:55
We do that by adding the virtual
keyword in between the properties access
2:00
modifier and the data type.
2:05
And then the ComicBookArtist entity.
2:13
Let's run the app and
see if we still get the expected output.
2:32
And, here's our list of comic books,
artists, and their roles.
2:36
So how does lazy loading work?
2:41
When the in memory representation of
our model is being created at runtime
2:45
EF will detect that our navigation
properties are marked as virtual and
2:49
create subclasses for those entities.
2:53
Within those subclasses, EF will
override our navigation properties.
2:56
The overridden properties give EF the
ability to detect when those properties
3:00
are accessed, and retrieve the data for
those properties when it's needed.
3:05
The derived entity types that EF
creates are called Dynamic Proxies.
3:10
Let's run our app again, but
this time we'll set a break point
3:17
at the beginning of our foreach loop so we
can inspect the collection of comic books.
3:20
Here we are at our break point.
3:33
I hover over the comicBooks variable
3:34
to see a preview of
the objects in the collection.
3:37
Normally we'd expect the value
of the items in our collection
3:41
to be the fully qualified type name for
the ComicBook entity class.
3:45
Which are case is,
ComicBookGalleryModel.models.ComicBook.
3:49
But with lazy loading enabled,
the type name is
3:54
System.Data.Entity.DynamicProxies.Comic-
Book
3:57
followed by a long string of letters and
numbers.
4:03
The long string of letters and numbers
is a hash of a generated description for
4:06
the entity that's been subclassed.
4:11
Go ahead and remove the break point and
press F5 to continue execution.
4:14
Now let's look at the queries that were
executed by EF to retrieve the data for
4:23
our application.
4:27
Remember when we were eagerly
loading related entities
4:29
EF executed a single query to
retrieve the necessary data.
4:32
With lazy loading enabled multiple queries
are needed in order to retrieve the data.
4:37
Here's the first query,
4:54
the query that EF executed to
retrieve the list of ComicBooks.
4:55
The second query is to load
the ComicBookArtist entities for
5:02
the first comic book that was
enumerated in our foreach loop.
5:06
Notice in the query right here, we can
see that we're filtering to the rows
5:12
who's comic book ID column values are
equal to something named @EntityKeyValue1.
5:18
@EntityKeyValue1 is a sequel parameter.
5:24
In the comment below that we can see
that the EntityKeyValue1 parameter value
5:29
was 1, which is the primary key value for
the first comic book in the list.
5:34
The next four queries are to get
the related artist and role entities, for
5:39
the first comic book artist entity.
5:43
Here's the query to get artist Id1.
5:46
And role Id1.
5:52
Artist Id2.
5:57
And role Id2.
6:01
The comic book artist, artist, and
roll entities need to be loaded in order
6:02
to get the displayed text for the comic
book artists and their associated rolls.
6:08
The next query is to
load the Series entity.
6:16
The Series entity needs to be loaded in
order to get the displayed text property
6:19
value which is a combination of
the series title property and
6:22
the comic book issue number property.
6:26
The next query is to get
the ComicBookArtist entities for the comic
6:29
book with an Id of two which is the second
comic book in our comic books collection.
6:33
Then the next query is to get
the ComicBookArtist entities for
6:41
the comic book with an Id of three.
6:45
What happened to the queries to get
the related Artist and Role entities for
6:48
the second comic book?
6:52
Since those entities
are the same as the entities for
6:54
the first comic book they're
already loaded into the context.
6:57
EF is able to detect this and
associate those entities
7:01
with the second comic book without having
to retrieve the data a second time.
7:05
Now let's look at the third option for
loading related entities.
7:13
Explicit loading.
7:17
To demonstrate explicit loading,
7:20
let's remove the virtual keyword from
the comic book series navigation property.
7:22
Now that we're not eagerly or lazy
loading the series navigation property,
7:28
the coming book displayed text
properties should not work properly.
7:33
And sure enough, we're just seeing
that issue number for each comic book.
7:37
To explicitly load the series navigation
property, let's add an if statement just
7:48
inside of the foreach loop that checks if
the comic book series property is null.
7:52
If comicBook.Series == null.
7:57
If the property is null
then we'll call the context
8:02
as entry method passing in the current
comicbook context.Entry(comicBook)..
8:07
The entry method returns a db entity
entry object for the referenced entity.
8:16
Every entity that has
been materialized and
8:22
tracked by the context has a db entity
entry object associated with it.
8:25
This object exposes two methods that
we can use to get the entry objects for
8:31
navigation properties.
8:35
Reference for
non-collection navigation properties and
8:40
collection, for
navigation collection properties.
8:45
The entry objects that are returned by
these methods provide a load method
8:50
that when called,
will load the related entity's.
8:54
Since the series property is
a non-collection navigation property,
8:58
we'll use the reference method to get
the entry for the navigation property.
9:02
Cb => cb.Series.
9:11
Then we'll call load on
the returned object.
9:22
.Load();.
9:25
Calling the load method will execute
a query against the database
9:29
every time that it's called.
9:32
That's why we need to check
if the series is null and
9:34
only call the load method if we need to,
9:37
otherwise we'd end up executing queries
for entities that were already loaded.
9:40
Now let's test our explicit
loading of the series entities.
9:45
And our output is back
to what it should be.
9:49
Let's take a look at the pros and
cons of each approach for
9:54
loading related entities.
9:57
When you see Eager Loading,
9:59
there will generally be fewer queries
executed against the database.
10:01
There are also be fewer surprises
as it forces you to plan upfront
10:05
with data you'll need for
your application.
10:10
Of the three options,
10:13
Lazy Loading is the easiest to use plus
you only load the data that you need.
10:14
On the downside,
10:20
as we saw in this video, Lazy Loading
can result in a lot of queries.
10:22
Explicit Loading gives you exact
control over the loading process.
10:27
Additionally, though we didn't
demonstrate it, you can load just part
10:31
of a related collection which isn't
possible with Eager or Lazy Loading.
10:36
The challenge with explicit
loading is that it requires
10:42
more thought and planning.
10:45
I tend to find that I use eager
loading more than the other options.
10:47
It's relatively easy to use and
I like its explicitness.
10:51
That being said, every situation is
different so consider the tradeoffs of
10:55
each option and pick the one that is the
best fit for your particular situation.
11:00
You need to sign up for Treehouse in order to download course files.
Sign up