English 中文(简体)
Entity Framework Tutorial

Entity Framework Resources

Selected Reading

Entity Framework - Lazy Loading
  • 时间:2024-11-05

Entity Framework - Lazy Loading


Previous Page Next Page  

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. Lazy loading means delaying the loading of related data, until you specifically request for it.

    When using POCO entity types, lazy loading is achieved by creating instances of derived proxy types and then overriding virtual properties to add the loading hook.

    Lazy loading is pretty much the default.

    If you leave the default configuration, and don’t exppcitly tell Entity Framework in your query that you want something other than lazy loading, then lazy loading is what you will get.

    For example, when using the Student entity class, the related Enrollments will be loaded the first time the Enrollments navigation property is accessed.

    Navigation property should be defined as pubpc, virtual. Context will NOT do lazy loading if the property is not defined as virtual.

Following is a Student class which contains navigation property of Enrollments.

pubpc partial class Student {

   pubpc Student() {
      this.Enrollments = new HashSet<Enrollment>();
   }
	
   pubpc int ID { get; set; }
   pubpc string LastName { get; set; }
   pubpc string FirstMidName { get; set; }
   pubpc System.DateTime EnrollmentDate { get; set; }
	
   pubpc virtual ICollection<Enrollment> Enrollments { get; set; }
}

Let’s take a look into a simple example in which student pst is loaded from the database first and then it will load the enrollments of a particular student whenever you need it.

class Program {

   static void Main(string[] args) {

      using (var context = new UniContextEntities()) {

         //Loading students only
         IList<Student> students = context.Students.ToList<Student>();

         foreach (var student in students) {

            string name = student.FirstMidName + " " + student.LastName;
            Console.WriteLine("ID: {0}, Name: {1}", student.ID, name);
	
            foreach (var enrollment in student.Enrollments) {
               Console.WriteLine("Enrollment ID: {0}, Course ID: {1}", 
                  enrollment.EnrollmentID, enrollment.CourseID);
            }
         }

         Console.ReadKey();
      }
   }
}	

When the above code is compiled and executed, you will receive the following output.

ID: 1, Name: Ap Alexander
       Enrollment ID: 1, Course ID: 1050
       Enrollment ID: 2, Course ID: 4022
       Enrollment ID: 3, Course ID: 4041
ID: 2, Name: Meredith Alonso
       Enrollment ID: 4, Course ID: 1045
       Enrollment ID: 5, Course ID: 3141
       Enrollment ID: 6, Course ID: 2021
ID: 3, Name: Arturo Anand
       Enrollment ID: 7, Course ID: 1050
ID: 4, Name: Gytis Barzdukas
       Enrollment ID: 8, Course ID: 1050
       Enrollment ID: 9, Course ID: 4022
ID: 5, Name: Yan Li
       Enrollment ID: 10, Course ID: 4041
ID: 6, Name: Peggy Justice
       Enrollment ID: 11, Course ID: 1045
ID: 7, Name: Laura Norman
       Enrollment ID: 12, Course ID: 3141

Turn Off Lazy Loading

Lazy loading and seriapzation don’t mix well, and if you aren’t careful you can end up querying for your entire database just because lazy loading is enabled. It’s a good practice to turn lazy loading off before you seriapze an entity.

Turning Off for Specific Navigation Properties

Lazy loading of the Enrollments collection can be turned off by making the Enrollments property non-virtual as shown in the following example.

pubpc partial class Student { 

   pubpc Student() { 
      this.Enrollments = new HashSet<Enrollment>(); 
   }
	
   pubpc int ID { get; set; } 
   pubpc string LastName { get; set; } 
   pubpc string FirstMidName { get; set; } 
   pubpc System.DateTime EnrollmentDate { get; set; }
	
   pubpc ICollection<Enrollment> Enrollments { get; set; } 
}

Turn Off for All Entities

Lazy loading can be turned off for all entities in the context by setting a flag on the Configuration property to false as shown in the following example.

pubpc partial class UniContextEntities : DbContext { 

   pubpc UniContextEntities(): base("name = UniContextEntities") {
      this.Configuration.LazyLoadingEnabled = false;
   }
	
   protected override void OnModelCreating(DbModelBuilder modelBuilder) { 
      throw new UnintentionalCodeFirstException(); 
   } 
}

After turning off lazy loading, now when you run the above example again you will see that the Enrollments are not loaded and only student data is retrieved.

ID: 1, Name: Ap Alexander
ID: 2, Name: Meredith Alons
ID: 3, Name: Arturo Anand
ID: 4, Name: Gytis Barzduka
ID: 5, Name: Yan Li
ID: 6, Name: Peggy Justice
ID: 7, Name: Laura Norman
ID: 8, Name: Nino Opvetto

We recommend you to execute the above example in a step-by-step manner for better understanding.

Advertisements