We are using Entity Framework Core 2.1.14 for a project. When I tried the two statements shown below, the SQL generated was different but both returned the related properties.
A HouseholdMmbrPrflhas
a 1:M relationship to HouseholdMemberIncomes
:
var test1 = await _dbContext.HouseholdMmbrPrfl
.Where(x => x.HouseholdMemberProfileId == memberId)
.FirstOrDefaultAsync();
var test2 = await _dbContext.HouseholdMmbrPrfl
.Include(x => x.HouseholdMemberIncomes)
.Where(x => x.HouseholdMemberProfileId == memberId)
.FirstOrDefaultAsync();
I thought an .Include
would be needed to get the HouseholdMemberIncomes
, but whenever I looked at test1 I see the HouseholdMemberIncomes
populated in the object, expanded the object I see the details but I didn't see another SQL query in my debug console.
I have the query being output as:
.UseLoggerFactory(LoggerFactory.Create(builder => builder.AddDebug())
I thought test1
would not have the HouseholdMemberIncomes
there. The query for test1
was only querying the HouseholdMmbrPrfl
table, the query was test2
I saw ran 2 queries once against HouseholdMmbrPrfl
and the 2nd against HouseholdMemberIncomes
When would you need .Include
if in either case the data was there, I assumed it was Lazy loading the properties but I could not find it enabled (no UseLazyLoadingProxies
) and the property is not virtual.
public List<HouseholdMemberIncome> HouseholdMemberIncomes { get; set; }
I assumed it was Lazy loading the properties but I could not find it enabled (no UseLazyLoadingProxies) and the Property is not virtual.
Since it is not lazy loaded this is happening due to the relationship fixup (see specifically the Fixup to locally tracked entities section of the docs and check out example provided there):
Relationship fixup also happens between entities returned from a tracking query and entities already tracked by the
DbContext
.
Basically if entity was already fetched by some query via the "current" context instance (and tracking is enabled) then the related entities will have the corresponding navigations filled when returned by the following query.
When would you need Include if in either case the data was there
Because it can be purely circumstantial (or even flat out wrong if you have not loaded all needed entities before, but only some of them). For example if you remove the code fetching the related data before then your code will break.