I stumbled across something today which had me quite stumped for a while and is worth blogging about. I feel like this is something I should have known, and probably did know, when I first read books and articles on the Entity Framework. But alas, if I did know, I had forgotten.
I was working with a repository which had a DbContext for data access, with both lazy loading and proxy enablement set to false. So, no proxies and no lazy loading.
I was iterating a list which did not include any “include” statements. So no related entities of the entities in the current list should have been eager loaded. However, I was noticing that there were related entities loaded for the entities in the list. Not all, but one particular related entity.
I had to get to the bottom of this, so I created a solution which used the raw DbContext, to rule out anything happening in the repository’s code that was loading the entities. (Note, I did read through the repository code and could not see any culprit.)
If you look at Figure 1 below, a list of
Person entities is displayed and I have maximised one as an example (that of Terry Halpin). You can see that the
Lendings related entity is
null. This is exactly what I would expect from a
DbContext, where there is no eager loading involved (no “includes”). So, for a while there I was convinced that something in the Repository was eager loading related entities, when not actually called upon to do so. And that would be bad.
Figure 1 – No Value for Lendings Related Entity
This bounced around in my head for a while and I was not convinced. Then, I had a “penny drop” moment when debugging the offending code ->>> perhaps the
Lendings were being retrieved and brought into memory (Local) at an earlier point in the program’s flow. I knew, for sure, that other things were being retrieved previously. So, if they are already in memory, were they automatically being referenced by the new objects, that were being loaded into memory, without any “include” statements?
So I went back to my small experimental solution to test my theory. That theory being:
If an entity is a related entity (the “Related Entity”) of another entity (the “Primary Entity”), and that Related Entity is already in memory by the time the Primary Entity is itself loaded, then the Related Entity will accordingly be a non-null member of the Primary Entity.
Now THAT was a mouthful, so I will elaborate with a screenshot. But before we look at it, quickly look back to Figure 1, where all that was being retrieved was a
Now look at Figure 2:
Figure 2 – Lendings Related Entity is now populated
There are 2 things to note:
- Before retrieving the
Person entities, I have retrieved a list of
Lending entities and forced the loading of that list, from the database, by calling
- Now, if you look at the same entity which I expanded in the
Person list (Terry Halpin), you will see that the
Lendings related entity is populated (not
null). But I have not used the
includes extension-method to eager load those Lendings.
Now I’m going to go walk my dog.