Loading Related Entities in Entity Framework

This article explains three methods to load 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 Lading Example....");

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

    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 Lading Example....");

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

    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 delay loading 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 or the entity is accessed.

Sample code

using (var context = new Entities())

{

    //With Object Context

    context.ContextOptions.LazyLoadingEnabled = true;

    //With DB Context

    //context.Configuration.LazyLoadingEnabled = true;

 

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

    var dep = context.DepartmentMasters.Where(f => f.DepartmentId == 1).FirstOrDefault();

    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 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 then it returns null.

static void Main(string[] args)

{

    using (var context = new Entities())

    {

        //With Object Context

        context.ContextOptions.LazyLoadingEnabled = false;

        //With DB Context

        //context.Configuration.LazyLoadingEnabled = false;

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

        if (emp.EmployeeDetail == null)

        {

            Console.WriteLine("No Employee Detail Data or Employee Detail is not loaded");

        }

        Console.ReadKey();

    }

}

Output

Explicitly Loading

Now I want to load the related detail data explicitly. There is a one-to-one relation between EmployeeMaster and the EmployeeDetail entity.

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

static void Main(string[] args)

{

    using (var context = new Entities())

    {

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

        if (emp.EmployeeDetail == null)

        {

            Console.WriteLine("No Employee Detail Data or Employee Detail is not loaded");

            Console.WriteLine("Loading Employee Detail Data....");

            if (!emp.EmployeeDetailReference.IsLoaded)

            {

                emp.EmployeeDetailReference.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:
 

static void Main(string[] args)

{

    using (var context = new Entities())

    {

        var dep = context.DepartmentMasters.Where(p => p.DepartmentId ==    1).FirstOrDefault();

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

        if (!dep.EmployeeMasters.IsLoaded)

        {

            dep.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.