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

Tuesday, July 19, 2011

Entity Framework and lazy loading interview questions

Lazy loading is the process whereby an entity or collection of entities is automatically loaded from the database the first time that a property referring to the entity/entities is accessed.

Let’s reuse our model defined for eager loading.


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; }
}

}


Question 1: How can you disable lazy loading of related entities accessed via navigation properties?

Lazy loading of the tasks for a project can be turned off by removing the virtual keyword for that navigation property.


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 List<Task> Tasks { get; set; }

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


In the Project definition above, lazy loading for Tasks has been disabled by removing the virtual keyword for Tasks. Of course, loading of Tasks can still be accomplished using the eager loading constructs or by using an explicit Load().

Question 2: How can you disable lazy loading for all entities?

Lazy loading can be turned off for all entities in the context by setting a flag on the Configuration property. This can be defined in the context:


public class EFDemoContext : DbContext
{
public EFDemoContext()
{
// disable lazy loading for all entities
this.Configuration.LazyLoadingEnabled = false;
}

public DbSet<Project> Projects { get; set; }
public DbSet<Task> Tasks { get; set; }
public DbSet<Employee> Employees { get; set; }
}

5 comments: