Search code examples
entity-frameworkasp.net-corelazy-loadingaspnetboilerplateef-core-2.0

Why do I have to Include other entities into my Linq query?


In the below query, why do I have to include the related entities in my query to get a value for them? I mean why Lazy-loading does not seem to work and do I have to do Eager-loading instead?

var acceptedHitchRequest = await _acceptedRequestRepository.GetAll()
                                                                    .Include(p => p.HitchRequest)
                                                                    .Include(p => p.CarparkRequest)
                                                                    .Include(p => p.HitchRequest.User)
                                                                    .Include(p => p.CarparkRequest.User)
                                                                    .Where(p => (input.HitchRequestId.HasValue ? p.HitchRequest.Id == input.HitchRequestId : p.CarparkRequest.Id == input.CarparkRequestId)
                                                                                && p.IsActive).FirstOrDefaultAsync();
            if (input.HitchRequestId.HasValue && acceptedHitchRequest.HitchRequest.CreatorUserId == AbpSession.UserId)

The CreatorUserId in the if condition would throw an exception because the HitchRequest would be null if I were not using the Include().


Solution

  • Inclue() method provides eager loading instead of lazy loading. I'm explaining to you the difference between the two based on my knowledge.

    • Lazy loading. It gives you records only for the entity itself and one each time that related data (in your case HitchRequest) for the entity must be retrieved. The DbContext class gives you lazy loading by default.

    • Eager loading. When the entity is read, related data is retrieved along with it. This typically results in a single join query that retrieves all of the data that's needed. You specify eager loading by using the Include method.

    The first statement without Include() is equivalent to the below statement, that's why HitchRequest is null if you don't use Include():

    SELECT * FROM AcceptedRequest;
    

    The statement which uses Include("HitchRequest.User") is equivalent to the below statement:

    SELECT * FROM AcceptedRequest JOIN Orders ON AcceptedRequest.Id = HitchRequest.User.AcceptedRequestId;
    

    You can refer to this very useful article.

    Entity Framework Loading Related Entities, Eager Loading and Eager Loading in Entity Framework