Understanding Lazy Loading, Eager Loading, and Explicit Loading in Entity Framework Core

Welcome everyone to a new post in the Entity Framework Core course! Today, we'll look at the different options Entity Framework Core provides for loading related data, depending on your application's needs.

 

 

Remember, all this code is available on GitHub. Before continuing with this post, I recommend checking out the one about relationships in Entity Framework Core.

 

 

1 - What is Eager Loading in Entity Framework Core

Even though we haven’t talked directly about what Eager Loading is, we have seen it indirectly. Eager Loading consists of directly loading the data related to your entity in the same query as the main entity.

 

In Entity Framework Core, you can do this when using dbSet with .Include():

[HttpGet("eager-loading")]public async Task<List<User>> EagerLoading()    => await _context.Users        .Include(a => a.Wokringexperiences)        .ToListAsync();

In this scenario, when loading users, we're including their working experiences in the same query, which in SQL translates to a join.

 

 

2 - What is Lazy Loading in Entity Framework Core

We also touched on lazy loading or deferred loading before when I explained IQueryable. Here’s when you load a main entity, but the related data isn’t loaded until you access the property on the entity.

 

Before making changes to your code, keep in mind that since .NET Core 3, you have to install the Microsoft.EntityFrameworkCore.Proxies package in your project, since it’s not included by default.

In the options, when including the DBContext, you must specify the following configuration:

services.AddDbContext<CursoEfContext>(options=>    options    .UseLazyLoadingProxies() // <----- HERE    .UseMySQL("server=127.0.0.1;port=4306;database=cursoEF;user=root;password=cursoEFpass"));

And finally, in the entity, it should be declared as virtual:

public virtual ICollection<Wokringexperience> Wokringexperiences { get; set; }

 

Now we can go into the logic itself. In our case, we change the code to the following, and the part where we query working experiences won’t execute until you reach the line that accesses it:

[HttpGet("lazy-loading/{userId}")]public async Task<User?> LazyLoading(int userId){    User? user = await _context.Users.FirstOrDefaultAsync(a => a.Id == userId);    if (user is not null)    {        var experiences = user.Wokringexperiences; // <---- HERE        if (experiences is not null && experiences.Any())        {            Console.WriteLine("this user has experiences");        }    }    return user;}

At first, this solution seems the best, but be careful—one query with a join, even if it has a lot of records, is very likely to be faster than many small queries. So, depending on what you want or are doing, you’ll need to choose wisely between Eager Loading and Lazy Loading.

 

These are the queries executed from the previous code:

example lazy loading csharp

  • Note: Do not confuse Lazy Loading in Entity Framework Core with Lazy<T> in .NET.

 

 

3 - Explicit Loading in Entity Framework Core

Finally, when we use explicit loading, it's very similar to lazy loading. We don’t load the data automatically; instead, we must specify it explicitly.

For example, if we load a user, and want to load their workingExperiences, we do it like this:

[HttpGet("explicit-loading/{userId}")]public async Task<User?> ExplicitLoading(int userId){    User? user = await _context.Users.FirstOrDefaultAsync(a => a.Id == userId);    if (user is not null)    {        await _context.Entry(user)            .Collection(a => a.Wokringexperiences)            .LoadAsync(); // <----- HERE                if (user.Wokringexperiences is not null && user.Wokringexperiences.Any())        {            Console.WriteLine("this user has experiences");        }    }    return user;}

As you can see, we're specifying the collection and then loading the data using the Load() / LoadAsync() method. Just like in lazy loading, it is done with a separate query.

 

One thing to keep in mind is that explicit loading can be used even when lazy loading is disabled (or the proxy isn’t enabled), so it can serve as a hack in some scenarios.

 

 

Conclusion

 

As with everything in software development, the choice between Lazy Loading, Eager Loading, and Explicit Loading will depend on your specific situation and requirements. I hope this post helps you make the best decision!

 

This post was translated from Spanish. You can see the original one here.
If there is any problem you can add a comment bellow or contact me in the website's contact form

© copyright 2025 NetMentor | Todos los derechos reservados | RSS Feed

Buy me a coffee Invitame a un café