Lazy Loading in Entity Framework Core

Lazy Loading in Entity Framework (EF) Core

In this article, I am going to discuss Lazy Loading in Entity Framework (EF) Core with Examples. Please read our previous article, where we discussed Eager Loading in Entity Framework Core with Examples. At the end of this article, you will understand what is Lazy Loading and how to implement Lazy Loading in EF Core. You will also learn how to disable Lazy Loading for a particular and for all entities, and finally, we will discuss when to use Lazy Loading in Entity Framework. We will work with the same example we have worked on so far.

Lazy Loading in Entity Framework Core

Lazy Loading is a Process where Entity Framework Core loads the related entities on demand. That means the related entities or child entities are loaded only when it is being accessed for the first time. So, in simple words, we can say that Lazy loading simply delays the loading of related entities until you specifically request it. 

Lazy loading is one feature that allows entities to be loaded on-demand rather than loaded all at once when querying the database. This means related data is not retrieved from the database until we access them explicitly. If this is not clear at the moment, don’t worry, I will explain this concept with some examples using EF Core.

So, in short,

  1. Lazy loading is a technique that loads and processes only the necessary data to operate the application. Data that is not currently needed remains untouched.
  2. The integration of this feature has significantly improved the performance and speed of the application, making it an essential part of the Entity Framework core.
Example to Understand Lazy Loading in Entity Framework:

Let us understand Lazy Loading in EF Core with an example. Please have a look at the following Student entity. If you look at the Student class, then you will find a navigation property for the StudentAddress entity. At the same time, you will also find a navigation property for Standard and a collection navigation property for Courses Entities.

Example to Understand Lazy Loading in Entity Framework

In Lazy Loading, the context object first loads the Student entity data from the database, and then it will load the related entities when you access those navigation properties for the first time. If you are not accessing the Navigation Properties, then it will not load those related data from the database.

For example, when executing the below statement, the context object will only load the Student table data using a SELECT SQL Statement. It will not load the related StudentAddress, Standard, or Courses table data.

Student? student = context.Students.FirstOrDefault(std => std.StudentId == 1);

Later, if you execute the below statement, when we access the StudentAddress Property for the First Time, the Context object will issue a SELECT SQL Statement and load the related StudentAddress data from the database table.

StudentAddress? studentAddress = student?.StudentAddress;

Similarly, when you execute the below statement, the Context object will generate and execute another SELECT SQL Statement to fetch the related data from the Standards database table.

Standard? standard = student?.Standard;

How to Implement Lazy Loading in EF Core?

We can implement Lazy loading in Entity Framework Core in two ways. They are as follows:

  1. Lazy loading With Proxies
  2. Lazy loading Without Proxies

Lazy loading With Proxies in EF Core:

To enable Lazy Loading using Proxies, the first step is to install the Proxy Package provided by Microsoft. This can be done by installing Microsoft.EntityFrameworkCore.Proxies package, which will add all the necessary proxies. There are three steps involved in enabling Lazy Loading using Proxies.

  1. Install Proxies Package
  2. Enable Lazy Loading using UseLazyLoadingProxies
  3. Mark the Property as Virtual
Step 1: Install Microsoft.EntityFrameworkCore.Proxies Package

So, open NuGet Package Manager UI by selecting Tools => NuGet Package Manager => Manage NuGet Packages for Solution from the Visual Studio Menu, which will open the following window. From this window, select the Search tab, then search for Microsoft.EntityFrameworkCore.Proxies package and select Microsoft.EntityFrameworkCore.Proxies package and click the Install button as shown in the image below.

Install Microsoft.EntityFrameworkCore.Proxies Package

Once you click on the Install button, it will open the Preview Changes window to tell what packages are going to be installed. Simply review the changes and click the OK button in the image below.

Install Microsoft.EntityFrameworkCore.Proxies Package

Once you click on the OK button, it will open the License Acceptance window. Simply click on the I Accept button as shown in the below image.

Install Microsoft.EntityFrameworkCore.Proxies Package

Once you click on the OK button, it will install the package, and you can verify the package inside the Dependencies => Packages folder of your project, as shown in the below image.

Install Microsoft.EntityFrameworkCore.Proxies Package

Alternatively, you can also Install Microsoft.EntityFrameworkCore.Proxies package using the Package Manager Console and .NET Core CLI Command as follows:

  1. [Package Manager Console]: install-package Microsoft.EntityFrameworkCore.Proxies
  2. [Dotnet CLI]: dotnet add package Microsoft.EntityFrameworkCore.Proxies
Step 2: Enable Lazy Loading using UseLazyLoadingProxies

Once we Install Microsoft.EntityFrameworkCore.Proxies package, then we need to use the UseLazyLoadingProxies method to enable the Lazy Loading in Entity Framework Core within the OnConfiguring method of the DbContext class.

optionsBuilder.UseLazyLoadingProxies();

So, modify the EFCoreDbContext context class as follows:

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
namespace EFCoreCodeFirstDemo.Entities
{
    public class EFCoreDbContext : DbContext
    {
        //Constructor calling the Base DbContext Class Constructor
        public EFCoreDbContext() : base()
        {
        }

        //OnConfiguring() method is used to select and configure the data source
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            //To Display the Generated the Database Script
            optionsBuilder.LogTo(Console.WriteLine, LogLevel.Information);

            //Enabling Lazy Loading
            optionsBuilder.UseLazyLoadingProxies();

            //Configuring the Connection String
            optionsBuilder.UseSqlServer(@"Server=LAPTOP-6P5NK25R\SQLSERVER2022DEV;Database=EFCoreDB1;Trusted_Connection=True;TrustServerCertificate=True;");
        }

        //OnModelCreating() method is used to configure the model using ModelBuilder Fluent API
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            //Use this to configure the model using Fluent API
        }

        //Adding Domain Classes as DbSet Properties
        public virtual DbSet<Course> Courses { get; set; }

        public virtual DbSet<Standard> Standards { get; set; }

        public virtual DbSet<Student> Students { get; set; }

        public virtual DbSet<StudentAddress> StudentAddresses { get; set; }

        public virtual DbSet<Teacher> Teachers { get; set; }
    }
}
Mark the Navigation Property as Virtual

Finally, we all need to mark the navigation property as virtual, which we want to Laod Lazily. So, if you see our Student, we have already marked the Navigation Properties as Virtual, as shown in the below image.

Mark the Navigation Property as Virtual

Note: If you are not marked the navigation properties as virtual, then please add the virtual keyword, and then as we already discussed, whenever we add or update domain classes, we need to sync the database with the model using add-migration and update-database commands using Package Manager Console or .NET Core CLI. So, please execute the add-migration and update-database commands.

Using Lazy Loading in EF Core:

Now, modify the Main method of the Program class as follows to use Lazy Loading in Entity Framework Core. The following example is self-explained, so please go through the comment line for a better understanding.

using EFCoreCodeFirstDemo.Entities;
using Microsoft.EntityFrameworkCore;
namespace EFCoreCodeFirstDemo
{
    internal class Program
    {
        static void Main(string[] args)
        {
            try
            {
                var context = new EFCoreDbContext();

                //Loading the particular student data only
                //Here, it will only load the Student Data, no related entities
                Student? student = context.Students.FirstOrDefault(std => std.StudentId == 1);
                Console.WriteLine($"Firstname: {student?.FirstName}, Lastname: {student?.LastName}");
                Console.WriteLine();

                //Loading the Student Address (it will execute Separate SQL query)
                StudentAddress? studentAddress = student?.StudentAddress;
                Console.WriteLine($"AddresLin1 {studentAddress?.Address1}, AddresLin2 {studentAddress?.Address2}");
                Console.WriteLine();

                //Loading the Standard (it will execute Separate SQL query)
                Standard? standard = student?.Standard;
                Console.WriteLine($"StandardName: {standard?.StandardName}, Description: {standard?.Description}");
                Console.WriteLine();

                //Loading the Course (it will execute separate SQL query)
                //var courses = student?.Courses;
                //if( courses != null )
                //{
                //    foreach (var course in courses)
                //    {
                //        Console.WriteLine($"CourseName: {course.CourseName}");
                //    }
                //}
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error: {ex.Message}"); ;
            }
        }
    }
}
Output:

Using Lazy Loading in EF Core

As you can see in the above output, it is issuing three different Select Statements to load the data from the database. This means it is using Lazy Loading to load the related data. Further, you can see that it is not loading the Courses table data, as we have commented on the statement which accessing the Courses navigation property.

Note: It’s important to be cautious of lazy loading as it can lead to unnecessary database roundtrips, commonly called the N+1 problem. It’s best to take preventative measures to avoid this issue.

Lazy Loading Without Proxies in Entity Framework Core:

The second method of enabling Lazy Loading in Entity Framework Core is using the ILazyLoader interface. Implementing Lazy-Loading Without Proxies in EF Core work is done by injecting the ILazyLoader service into an entity.

  1. The ILazyLoader interface is responsible for loading navigation properties that have not yet been loaded.
  2. The feature can be easily integrated into the main component of the database. That is to the Principal Entity.
  3. To use the ILazyLoader, it is necessary to install Microsoft.EntityFrameworkCore.Abstraction Package.
Step 1: Install Microsoft.EntityFrameworkCore.Abstraction Package

So, open NuGet Package Manager UI by selecting Tools => NuGet Package Manager => Manage NuGet Packages for Solution from the Visual Studio Menu, which will open the following window. From this window, select the Search tab, then search for Microsoft.EntityFrameworkCore.Abstraction package and select Microsoft.EntityFrameworkCore.Abstraction package and click the Install button, as shown in the image below.

Install Microsoft.EntityFrameworkCore.Abstraction Package

Once you click on the Install button, it will open the Preview Changes window to tell what packages are going to be installed. Simply review the changes and click the OK button in the image below.

Install Microsoft.EntityFrameworkCore.Abstraction Package

Once you click on the OK button, it will open the License Acceptance window. Simply click on the I Accept button as shown in the below image.

Install Microsoft.EntityFrameworkCore.Abstraction Package

Once you click on the OK button, it will install the package, and you can verify the package inside the Dependencies => Packages folder of your project, as shown in the below image.

Install Microsoft.EntityFrameworkCore.Abstraction Package

Alternatively, you can also Install Microsoft.EntityFrameworkCore.Abstraction package using the Package Manager Console and .NET Core CLI Command as follows:

  1. [Package Manager Console]: install-package Microsoft.EntityFrameworkCore.Abstraction
  2. [Dotnet CLI]: dotnet add package Microsoft.EntityFrameworkCore.Abstraction
Step 2: Alter the Principal Entity

Once you install Microsoft.EntityFrameworkCore.Abstraction Package, then we need to alter the Principal entity to include the following.

  1. A using directive for Microsoft.EntityFrameworkCore.Infrastructure
  2. A private field for the ILazyLoader instance
  3. An empty constructor and one parameterized that takes an ILazyLoader as a parameter to Initialize the ILazyLoader instance.
  4. A private field for the navigation property
  5. A public getter and setter property for the navigation property that uses the ILazyLoader.Load method.

In our example, the Student Entity is the Principal Entity, So please modify the Student Entity as follows to include the above-discussed thing so that it can lazily load the related entities. The following example code is self-explained, so please go through the comment lines for a better understanding.

//Adding the namespace
using Microsoft.EntityFrameworkCore.Infrastructure;

namespace EFCoreCodeFirstDemo.Entities
{
    public class Student
    {
        //A private field for the ILazyLoader instance
        private readonly ILazyLoader _lazyLoader;

        //An empty constructor 
        public Student()
        {
        }

        //one parameterized that takes an ILazyLoader as a parameter to
        //Initialize the ILazyLoader instance
        public Student(ILazyLoader lazyLoader)
        {
            _lazyLoader = lazyLoader;
        }

        public int StudentId { get; set; }

        public string? FirstName { get; set; }

        public string? LastName { get; set; }

        public int? StandardId { get; set; }

        //Private Field For Standard Navigation Property
        private Standard _Standard;

        //Public Setter and Getter Property for the Private _Standard Field
        public Standard Standard
        {
            get => _lazyLoader.Load(this, ref _Standard);
            set => _Standard = value;
        }

        //public virtual StudentAddress? StudentAddress { get; set; }

        //Private Field For StudentAddress Navigation Property
        private StudentAddress _StudentAddress;

        //Public Setter and Getter Property for the Private _StudentAddress Field
        public StudentAddress StudentAddress
        {
            get => _lazyLoader.Load(this, ref _StudentAddress);
            set => _StudentAddress = value;
        }

        //Private Field For Course Collection Navigation Property
        private ICollection<Course> _Courses = new List<Course>();

        //Public Setter and Getter Property for the Private _Courses Field
        public ICollection<Course> Courses
        {
            get => _lazyLoader.Load(this, ref _Courses);
            set => _Courses = value;
        }
    }
}

Next, modify the EFCoreDbContext class as follows.

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
namespace EFCoreCodeFirstDemo.Entities
{
    public class EFCoreDbContext : DbContext
    {
        //Constructor calling the Base DbContext Class Constructor
        public EFCoreDbContext() : base()
        {
        }

        //OnConfiguring() method is used to select and configure the data source
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            //To Display the Generated the Database Script
            optionsBuilder.LogTo(Console.WriteLine, LogLevel.Information);

            //Configuring the Connection String
            optionsBuilder.UseSqlServer(@"Server=LAPTOP-6P5NK25R\SQLSERVER2022DEV;Database=EFCoreDB1;Trusted_Connection=True;TrustServerCertificate=True;");
        }

        //OnModelCreating() method is used to configure the model using ModelBuilder Fluent API
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            //Use this to configure the model using Fluent API
        }

        //Adding Domain Classes as DbSet Properties
        public virtual DbSet<Course> Courses { get; set; }

        public virtual DbSet<Standard> Standards { get; set; }

        public virtual DbSet<Student> Students { get; set; }

        public virtual DbSet<StudentAddress> StudentAddresses { get; set; }

        public virtual DbSet<Teacher> Teachers { get; set; }
    }
}

We don’t need to make any changes to the Main method. So, now, run the application, and you should get the following output as expected. As you can see, EF Core is using separate SELECT SQL Statements to load the related entities.

Lazy Loading Without Proxies in Entity Framework Core

How to Disable Lazy Loading in EF Core?

So, basically, if we want to disable Lazy Loading for the whole application, then we need to use the LazyLoadingEnabled property of ChangeTracker class, and we need to set this property value to true within the constructor of context class as shown in the below image.

How to Disable Lazy Loading in EF Core?

So, modify the EFCoreDbContext class as follows to disable Lazy Loading for the whole application in Entity Framework Core.

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
namespace EFCoreCodeFirstDemo.Entities
{
    public class EFCoreDbContext : DbContext
    {
        //Constructor calling the Base DbContext Class Constructor
        public EFCoreDbContext() : base()
        {
            //Disabling Lazy Loading
            this.ChangeTracker.LazyLoadingEnabled = false;
        }

        //OnConfiguring() method is used to select and configure the data source
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            //To Display the Generated the Database Script
            optionsBuilder.LogTo(Console.WriteLine, LogLevel.Information);

            //Configuring the Connection String
            optionsBuilder.UseSqlServer(@"Server=LAPTOP-6P5NK25R\SQLSERVER2022DEV;Database=EFCoreDB1;Trusted_Connection=True;TrustServerCertificate=True;");
        }

        //OnModelCreating() method is used to configure the model using ModelBuilder Fluent API
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            //Use this to configure the model using Fluent API
        }

        //Adding Domain Classes as DbSet Properties
        public virtual DbSet<Course> Courses { get; set; }

        public virtual DbSet<Standard> Standards { get; set; }

        public virtual DbSet<Student> Students { get; set; }

        public virtual DbSet<StudentAddress> StudentAddresses { get; set; }

        public virtual DbSet<Teacher> Teachers { get; set; }
    }
}

With these changes in place, if you run the application, you will see that the related entities will not be loaded when we access them, as shown in the image below.

How to Disable Lazy Loading in EF Core?

The default value of LazyLoadingEnabled is set to true. This is why although we have not set this property value to true, Lazy Loading is still working in our application. Even if you want, then while accessing the data, you can enable and disable lazy loading.

For a better understanding, please have a look at the following example. In the example below, we are disabling the Lazy Loading using the statement context after fetching the Student data, i.e., ChangeTracker.LazyLoadingEnabled = false; hence it will not load the Standard data. Then we again enabled the Lazy loading by using the context.ChangeTracker.LazyLoadingEnabled = true; statement, and then we are accessing the StudentAddress navigation property, and this time as Lazy Loading is enabled, it will issue a separate SELECT SQL Statement and load the Student Address data.

using EFCoreCodeFirstDemo.Entities;
using Microsoft.EntityFrameworkCore;
namespace EFCoreCodeFirstDemo
{
    internal class Program
    {
        static void Main(string[] args)
        {
            try
            {
                var context = new EFCoreDbContext();

                //Loading the particular student data only
                //Here, it will only load the Student Data, no related entities
                Student? student = context.Students.FirstOrDefault(std => std.StudentId == 1);
                Console.WriteLine($"Firstname: {student?.FirstName}, Lastname: {student?.LastName}");
                Console.WriteLine();

                //I want to Disable Lazy Loading Here
                context.ChangeTracker.LazyLoadingEnabled = false;

                //As Lazy Loading is Disabled so, it will not load the Standard data
                Standard? standard = student?.Standard;
                Console.WriteLine($"StandardName: {standard?.StandardName}, Description: {standard?.Description}");
                Console.WriteLine();

                //I want to Enable Lazy Loading Here
                context.ChangeTracker.LazyLoadingEnabled = true;

                //As Lazy Loading is Enabled so, it will load the StudentAddress data
                StudentAddress? studentAddress = student?.StudentAddress;
                Console.WriteLine($"AddresLin1 {studentAddress?.Address1}, AddresLin2 {studentAddress?.Address2}");
                Console.WriteLine();
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error: {ex.Message}"); ;
            }
        }
    }
}
Output:

Advantages and Disadvantages of using Lazy Loading in EF Core

Advantages of using Lazy Loading in EF Core:

Lazy loading in Entity Framework Core (EF Core) offers several advantages that can simplify code, improve memory usage, and provide a more efficient approach to data retrieval. Here are some key advantages of using lazy loading:

  1. On-Demand Data Loading: With lazy loading, related entities are only loaded from the database when they are accessed for the first time. This helps minimize unnecessary data retrieval and improve performance by loading data only when needed.
  2. Simpler Code: Lazy loading allows you to write more focused and concise code. You can access related properties and collections without needing to explicitly load them, leading to cleaner and more maintainable code.
  3. Reduced Initial Query Time: Lazy loading can help reduce the initial query execution time because only the data required for the current operation is loaded. This can lead to a more responsive user experience.
  4. Optimal Memory Usage: Lazy loading avoids loading unnecessary related data, which can help optimize memory usage, especially when dealing with large object graphs or datasets.
  5. Easier Initialization: Lazy loading allows you to initialize objects quickly without loading their entire graph of related data. This can be useful when you need to display a summary or preview of an entity before loading all its details.
  6. Performance in Write-Heavy Scenarios: In scenarios where your application writes data more frequently than it reads, lazy loading can reduce the overhead of loading unnecessary related data.
  7. Avoidance of Over-Fetching: Lazy loading can help prevent over-fetching of data, especially when only a subset of related data is required for a specific operation.
  8. Delayed Query Execution: Lazy loading allows you to delay query execution until it’s absolutely necessary. This can be advantageous when building complex queries or applying additional filtering before data retrieval.
  9. Granular Control: You can choose which related properties or collections to access, giving you granular control over what data is actually loaded.
  10. Minimized Database Load: Lazy loading can reduce the number of database queries, potentially leading to better utilization of database resources.
Disadvantages of using Lazy Loading in EF Core

While lazy loading in Entity Framework Core (EF Core) offers certain benefits, it also comes with several disadvantages and potential pitfalls that you should be aware of. Here are some key disadvantages of using lazy loading:

  1. N+1 Query Problem: One of the most significant disadvantages of lazy loading is the N+1 query problem. When you access a lazy-loaded property or collection for multiple entities, EF Core might issue individual database queries for each entity, leading to a large number of database round-trips and potentially impacting performance.
  2. Performance Overhead: Lazy loading introduces a performance overhead when accessing lazy-loaded properties or collections. Each access triggers an additional database query, which can impact response time, especially in scenarios with a high number of lazy loads.
  3. The Complexity of Debugging: The N+1 query problem and unexpected data retrieval can make debugging more challenging. Identifying which part of your code is causing excessive database queries may be difficult.
  4. Unpredictable Timing of Data Retrieval: Lazy loading can lead to unexpected data retrieval, as related data is loaded on-demand when accessed. This can make the timing of data retrieval less predictable and might result in data retrieval occurring at unexpected points in your application’s execution.
  5. Inefficient Use of Database Resources: Lazy loading can result in inefficient database queries, especially if related data is accessed in a loop or during iteration. The separate queries might not be optimized for performance.
  6. Possible Performance Bottlenecks: In situations where a large number of entities are loaded with numerous lazy-loaded properties, the excessive number of database queries can become a performance bottleneck.
  7. Data Transfer Impact: Lazy loading can impact data transfer between layers or components of your application, potentially leading to increased serialization and deserialization times.
  8. Connection Lifetime: Lazy loading requires that the DbContext is still alive and connected when lazy-loaded properties or collections are accessed. This can affect scenarios where entities are detached or when dealing with long-lived contexts.
  9. Limited Control Over Query Optimization: With lazy loading, you have less control over query optimization. EF Core generates queries on-the-fly as properties are accessed, potentially resulting in suboptimal query plans.
  10. Maintenance Complexity: As your application evolves, adding or removing lazy-loaded properties might impact the efficiency of your data retrieval patterns. This can introduce maintenance challenges.
  11. Risk of Over-Lazy Loading: Lazy loading might lead to over-fetching of data, where you inadvertently load more data than necessary, affecting both performance and memory usage.
When to use Lazy Loading in EF Core?

Lazy loading in Entity Framework Core (EF Core) can be useful in specific scenarios where you want to defer the loading of related data until it’s actually accessed. Here are some situations where using lazy loading might be appropriate:

  1. Minimizing Initial Query Time: Lazy loading can help reduce the initial query execution time by loading only the main entity’s data upfront. This can lead to a more responsive user experience, particularly in scenarios where quick loading is critical.
  2. Accessing Specific Related Data: When you only need to access a subset of related data for a specific operation, lazy loading can help avoid over-fetching of data. This is especially relevant when working with large or complex object graphs.
  3. Deferred Loading: Lazy loading allows you to defer the retrieval of related data until it’s actually needed, which can help improve data access efficiency and minimize unnecessary data retrieval.
  4. Memory Efficiency: Lazy loading can help optimize memory usage by loading related data only when it’s accessed rather than loading all related data upfront.
  5. Complex Queries: If you have queries that involve multiple levels of related data, lazy loading can help avoid complex joins in initial queries, simplifying query construction and execution.
  6. Postponing Data Loading: Lazy loading can be beneficial when you want to initialize an object quickly without loading its entire graph of related data. This can be useful for displaying summaries or previews of entities.
  7. Performance in Read-Heavy Scenarios: In scenarios where your application reads data more frequently than it writes, lazy loading can help reduce the overhead of loading unnecessary related data.
  8. Granular Control: Lazy loading allows you to choose which specific related properties or collections to access, giving you granular control over what data is actually loaded.
  9. Optimizing Data Retrieval Sequence: Lazy loading can be useful when you want to optimize the sequence of data retrieval based on your application’s specific usage patterns.
What is the Difference Between Eager Loading and Lazy Loading in EF Core?

Eager loading and lazy loading are two different approaches to loading related data in an object-relational mapping (ORM) framework like Entity Framework Core. They have distinct characteristics and use cases. Here’s a breakdown of the key differences between eager loading and lazy loading:

  1. Eager Loading:
    • Definition: Eager loading involves loading related entities along with the main entity in a single query all at once.
    • Data Retrieval: All required data is retrieved from the database upfront, minimizing the need for additional queries during runtime.
    • Usage: Eager loading is suitable when you know you will need related data for a specific operation and want to minimize database round-trips.
    • Method: In Entity Framework Core, you use the Include and ThenInclude methods to specify which related entities to load eagerly.
    • Advantages:
      • Reduces database round-trips.
      • Improves initial query performance.
      • Simplifies code by providing a consistent and predictable data access pattern.
    • Disadvantages:
      • This may lead to over-fetching of data.
      • Complex queries can be generated.
      • It might not be suitable for all scenarios, such as cases where only a subset of related data is needed.
  2. Lazy Loading:
    • Definition: Lazy loading involves loading related entities only when they are accessed for the first time. Data is retrieved on demand.
    • Data Retrieval: Related data is fetched from the database as properties or collections are accessed in code.
    • Usage: Lazy loading is suitable when you want to defer loading related data until it’s actually needed to avoid unnecessary data retrieval.
    • Method: In Entity Framework Core, properties are marked as virtual to enable lazy loading. It’s enabled by default in EF Core, but you can also configure it explicitly.
    • Advantages:
      • Minimizes initial query execution time.
      • Efficiently uses memory by loading data only when needed.
      • Provides on-demand access to related data, reducing over-fetching.
    • Disadvantages:
      • This can lead to the N+1 query problem (multiple queries for each entity).
      • Introduces performance overhead when accessing lazy-loaded properties.
      • Requires careful management to avoid unexpected data retrieval and optimize performance.

In summary, eager loading is about loading all necessary data upfront to reduce database round-trips, while lazy loading focuses on deferring data retrieval until it’s accessed. The choice between these two approaches depends on your application’s requirements, data access patterns, and performance considerations. In some cases, combining both techniques and explicit loading can provide an optimal balance between performance and data retrieval.

Which is good – Eager Loading or Lazy Loading in Entity Framework Core?

Before making a decision on which approach to use, we must consider the application requirements and goals. Lazy Loading and Eager Loading have their strengths and weaknesses, and we have observed significant performance differences when using each method to accomplish the same task.

The choice between eager loading and lazy loading in Entity Framework Core (EF Core) depends on your specific application requirements, data access patterns, and performance considerations. There is no one-size-fits-all answer, as both techniques have their own strengths and weaknesses. Let’s explore some scenarios where each approach might be more suitable:

Eager Loading:

Eager loading is generally beneficial in the following situations:

  1. Displaying Data: When you know you will need related data for a specific operation, eager loading can help reduce database round-trips and improve initial query performance. This is common when displaying data to users, generating reports, or populating view models.
  2. Avoiding N+1 Query Problem: Eager loading is useful to address the N+1 query problem, where lazy loading could lead to multiple database queries for each entity in a collection.
  3. Complex Queries: When your queries involve multiple levels of related data, eager loading can simplify query construction and improve overall performance.
  4. Small Related Data: Eager loading can be effective when dealing with small amounts of related data that are commonly accessed together.
Lazy Loading:

Lazy loading is generally beneficial in the following situations:

  1. Minimizing Initial Query Time: Lazy loading can reduce the initial query execution time, making your application feel more responsive to users.
  2. Deferred Data Retrieval: When you want to avoid loading unnecessary related data upfront and retrieve only what’s needed, lazy loading is a suitable approach.
  3. Memory Efficiency: Lazy loading helps optimize memory usage by loading data on-demand, which is beneficial for large object graphs or datasets.
  4. Granular Data Access: When you want to selectively load specific related properties or collections based on user interactions or specific use cases, lazy loading provides fine-grained control.
  5. Read-Heavy Scenarios: In scenarios where your application reads data more frequently than it writes, lazy loading can reduce the overhead of loading unnecessary related data.
  6. Complex Initialization: When you want to initialize an object quickly without loading its entire graph of related data, lazy loading allows you to defer loading until necessary.

In real-time, many applications use a combination of both techniques and might even employ explicit loading for even more control over data retrieval. Consider the following factors when making your decision:

  1. Data Access Patterns: How your application accesses data and the specific requirements for each operation.
  2. Performance Goals: Whether you prioritize initial query performance, responsiveness, memory efficiency, or some combination of these factors.
  3. Data Volume: The size of your data sets and the potential impact on over-fetching or performance bottlenecks.
    User Experience: How the chosen loading strategy affects your application’s user experience and responsiveness.

Ultimately, the best approach depends on your specific use case, and you should carefully evaluate the pros and cons of each technique based on your application’s unique requirements.

In the next article, I am going to discuss Explicit Loading in Entity Framework Core with Examples. In this article, I try to explain the Lazy Loading in Entity Framework Core with Examples, and I hope you enjoyed this Lazy Loading in EF Core with Examples article. Please give your valuable feedback and suggestions about this article.

Leave a Reply

Your email address will not be published. Required fields are marked *