Loading Related Entities in Entity Framework

Introduction

Entity Framework supports the following three methods to load related data.

  • Eager Loading
  • Lazy Loading
  • Explicit Loading

Eager Loading

In Eager Loading, all relevant data for an entity is loaded at the time of the query of the entity in the context object. Eager Loading can be done by using the "Include" method. To perform Eager Loading, Lazy Loading must be disabled. Lazy Loading is enabled by default in Entity Framework.

Eager loading

Example

Suppose I have the three tables DepartmentMaster, EmployeeMaster, and EmployeeDetails. The relation among these three tables is shown in the following diagram.

relation tables

Example Code

using (var context = new Entities())
{
    Console.WriteLine("Eager Loading Example....");

    var dep = context.DepartmentMasters
        .Include(dm => dm.EmployeeMasters)
        .FirstOrDefault(f => f.DepartmentId == 1);

    foreach (var emp in dep.EmployeeMasters)
    {
        Console.WriteLine(emp.Code);
    }

    Console.ReadKey();
}

Output

Output

Eager Loading at multiple levels

We can also eagerly load multiple levels of related entities. In the following example, it loads the related entity Department, Employee Master, and Detail.

Sample Code

using (var context = new Entities())
{
    Console.WriteLine("Eager Loading Example....");

    var dep = context.DepartmentMasters
        .Include(dm => dm.EmployeeMasters.Select(em => em.EmployeeDetail))
        .FirstOrDefault(f => f.DepartmentId == 1);

    foreach (var emp in dep.EmployeeMasters)
    {
        Console.WriteLine($"Code: {emp.Code} Email Address: {emp.EmployeeDetail.PersonalEmail}");
    }

    Console.ReadKey();
}

Output

Eager Loading at multiple levels

Lazy Loading

Lazy Loading means delayed loading of the related entities. In Lazy Loading, a related entity or collection of entities is loaded from the database for the first time that a property is referred to or the entity is accessed.

Sample code

using (var context = new Entities())
{
    context.Configuration.LazyLoadingEnabled = true; // If using DbContext

    Console.WriteLine("Lazy Loading Example....");

    var dep = context.DepartmentMasters
        .Include(dm => dm.EmployeeMasters.Select(em => em.EmployeeDetail))
        .FirstOrDefault(f => f.DepartmentId == 1);

    foreach (var emp in dep.EmployeeMasters)
    {
        Console.WriteLine($"Code: {emp.Code} Email Address: {emp.EmployeeDetail.PersonalEmail}");
    }

    Console.ReadKey();
}

Output

Lazy Loading

In the code above, initially, one query is fired to fetch Department Master data. When the Employee Masters property of the Department is accessed, the Entity Framework loads the related data automatically. In short, whenever the navigation property is accessed, the Entity Framework loads the related entity from the database. In the example above if one department has two employees then the for loop retrieves the related employee as well as the employee details table from the database.

Explicit Loading

If Lazy Loading is disabled then it is still possible to fetch the related entities without the use of Eager Loading. It is possible with Explicit Loading. To explicitly retrieve the related entities from the database we can use the "Load" method. In the following example, If Lazy Loading is disabled then when I check whether the employee has related detail data it returns null.

Output

using (var context = new Entities())
{
    context.Configuration.LazyLoadingEnabled = false; // If using DbContext

    var emp = context.EmployeeMasters.FirstOrDefault(p => p.EmployeeId == 1);

    if (emp.EmployeeDetail == null)
    {
        Console.WriteLine("No Employee Detail Data or Employee Detail is not loaded");
    }

    Console.ReadKey();
}

Explicitly Loading

Now I want to load the related detail data explicitly. There is a one-to-one relationship between EmployeeMaster and the EmployeeDetail entity. The following will explicitly load one-to-one related entities

using (var context = new Entities())
{
    var emp = context.EmployeeMasters.FirstOrDefault(p => p.EmployeeId == 1);

    if (emp.EmployeeDetail == null)
    {
        Console.WriteLine("No Employee Detail Data or Employee Detail is not loaded");
        Console.WriteLine("Loading Employee Detail Data....");

        if (!context.Entry(emp).Reference(e => e.EmployeeDetail).IsLoaded)
        {
            context.Entry(emp).Reference(e => e.EmployeeDetail).Load();
            Console.WriteLine("Employee Detail Data load Complete....");
            Console.WriteLine("Employee Email: " + emp.EmployeeDetail.PersonalEmail);
        }
    }

    Console.ReadKey();
}

Output

Explicitly Load one to one related entities

The following will explicitly load one-to-many related entities

using (var context = new Entities())
{
    var dep = context.DepartmentMasters.FirstOrDefault(p => p.DepartmentId == 1);

    Console.WriteLine("Department Employees are not currently loaded");

    if (!context.Entry(dep).Collection(d => d.EmployeeMasters).IsLoaded)
    {
        context.Entry(dep).Collection(d => d.EmployeeMasters).Load();

        Console.WriteLine("Department Employees load complete");

        foreach (var emp in dep.EmployeeMasters)
        {
            Console.WriteLine(emp.Code);
        }
    }

    Console.ReadKey();
}

Output

Explicitly Load one to many related entities

Conclusion

Both the Lazy Loading and Explicit Loading make multiple round trips to the database to load related entities while Eager Loading retrieves all the related data in a single round trip to the database.


Similar Articles