Please navigate to the bottom of the page for Table of Contents

Tuesday, July 19, 2011

Entity Framework and eager loading of related entities interview questions

Question: Using the DbContext API’s in Entity Framework 4.1, explain the concept of eager loading related entities.

Eager loading can be defined as a directive to include related entities when loading an entity in a query. Eager loading is achieved by use of the Include() method.

Let us assume this simple code first model of Project and Tasks which we discussed in our earlier post of data annotations in Entity Framework.


using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

namespace EFDemo.Model
{
// Code first relies on a programming pattern
// referred to as convention over configuration.
// What this means is that if you want to use code first,
// your classes need to follow the certain conventions
// while defining schema.
// This allows EF to infer the schema that it needs to
// create to get the job done.
public class Project
{
// Code First has to be told that
// this as the primary key column
[Key]
public int UniqueProjectIdentifier { get; set; }
// this becomes a non-nullable column
[Required]
public string Name { get; set; }
// references the complex type as part of the
// project object in the database
public ProjectDetails Details { get; set; }
// list of tasks for a project
public virtual List<Task> Tasks { get; set; }

[NotMapped]
public string ProjectCode
{
get { return UniqueProjectIdentifier + Name;}
}
}

[ComplexType]
public class ProjectDetails
{
public DateTime? DateCreated { get; set; }
[MaxLength(500, ErrorMessage = "Maximum of 500 characters please")]
[MinLength(10, ErrorMessage = "Minimum of 10 characters required")]
public string Description { get; set; }
}

[Table("ProjectItems")]
public class Task
{
// Code First infers this as the primary key column
public int TaskId { get; set; }
public string Name { get; set; }

[Column("CreationDate")]
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }

// this is inferred as Foreign key to project table
public int ProjectId { get; set; }

// explicitly define the FK
[ForeignKey("ProjectId")]
public virtual Project Project { get; set; }

public Employee CreatedBy { get; set; }
public Employee UpdatedBy { get; set; }
}

public class Employee
{
public int Id { get; set; }
public string name { get; set; }

[InverseProperty("CreatedBy")]
public List<Task> TasksCreated { get; set; }
[InverseProperty("UpdatedBy")]
public List<Task> TasksUpdated { get; set; }
}

}


To eagerly load the tasks for all projects or a specific projects, we can use one of the following ways:


using (var context = new EFDemoContext())
{
// Load all projects and the associated tasks
var allprojects = context.Projects
.Include(p => p.Tasks)
.ToList();

// Load a specific project and all its tasks
var efProj = context.Projects
.Where(p => p.Name == "EF Demo")
.Include(p => p.Tasks)
.FirstOrDefault();

// Load all projects and related tasks using a string
// to specify the relationship
var allprojectsUsingString = context.Projects
.Include("Tasks")
.ToList();

// Load a specific project and its tasks using a string
// to specify the relationship
var efProj2 = context.Projects
.Where(p => p.Name == "EF Demo")
.Include("Tasks")
.FirstOrDefault();
}


Question 2: How can we eagerly load multiple levels of related entities?

Using the model above, we can load the projects, tasks and employees in multiple ways:

// load all employees, tasks and projects
var allData = context.Employees
.Include(e => e.TasksCreated.Select(t => t.Project))
.ToList();

// load all employees, tasks and projects
var allData2 = context.Projects
.Include(p => p.Tasks.Select(t=>t.CreatedBy))
.ToList();


In the next post we will review the lazy loading concepts of Entity Framework.

3 comments: