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.
Example
Suppose I have the three tables DepartmentMaster, EmployeeMaster, and EmployeeDetails. The relation among these three tables is shown in the following diagram.
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
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
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
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();
}
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
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
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.