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

Entity Framework Core is a powerful ORM that makes it easy to work with databases in .NET applications. One of the most important features of EF Core is its ability to load related data. In this article, we will discuss three different ways to load related data in EF Core: lazy loading, eager loading, and explicit loading.

Lazy Loading:

Lazy loading is a feature of EF Core that allows related entities to be loaded automatically when they are accessed for the first time. Lazy loading is enabled by default in EF Core for navigation properties that are marked as virtual.

Here's an example:

using (var context = new YourDbContext())
{
    var author = context.Authors.FirstOrDefault(a => a.Id == authorId);
    var books = author.Books;
}

When you look at the above code snippet closely, you'll notice that we're loading an author entity into memory. However, the Books property is not being loaded with it because we didn't include it in our query.

On the line when we're accessing the Books property of the author model, what's happening underneath is that EF Core is constructing & sending a SQL query to the database to fetch the related Books data belonging to the author.

Now, this can cause additional round trips to the database which can lead to some serious performance implications if not used with caution.

Eager Loading:

In eager loading, we're querying for the main entity along with its related data in a single SQL query.

Tip: Related data in this context are entities that share one-to-many or many-to-many relationships with the main entity.

We use eager loading when we know the entities that we'll be needing aforehand. This approach reduces the number of times we have to go to the database (database roundtrips) to fetch data thereby improving the performance of our application.

We can achieve eager loading in Ef core by simply using the include() method which allows us to specify additional entities to load when constructing our SQL query. Here is an example below:

using (var context = new YourDbContext())
{
    var author = context.Authors
        .Include(a => a.Books)
        .FirstOrDefault(a => a.Id == authorId);
}

Tip: You'll notice that we included the related books entities when querying for the author. With this, we don't need to send additional queries to the database when we want to work with the books property of the author.

Explicit Loading:

Explicit loading is a technique in which we load the related entities on-demand but in a separate query from the main query. Explicit loading is useful when we want to selectively load related entities based on user actions.

To explicitly load related entities in EF Core, we can use the Load() method on the related entity's navigation property. Here's an example:

using (var context = new YourDbContext())
{
    var author = context.Authors.FirstOrDefault(a => a.Id == authorId);
    context.Entry(author).Collection(a => a.Books).Load();
}

In this case, we are loading the author first and then using the Load() method to explicitly load their books. This can be useful when we want to load related entities on-demand, but still, avoid lazy loading's potential performance issues.

In summary, lazy loading is useful when we want to load related entities automatically, eager loading is useful when we want to load related entities along with the main entity in a single query, and explicit loading is useful when we want to selectively load related entities on demand.

In conclusion, understanding the differences between lazy loading, eager loading, and explicit loading is essential for building efficient and scalable EF Core applications. By using the appropriate loading technique for each scenario, we can improve performance and reduce the number of database round-trips in our applications.