Entity Framework - ขี้เกียจโหลด

การโหลดแบบขี้เกียจเป็นกระบวนการที่เอนทิตีหรือคอลเลกชันของเอนทิตีถูกโหลดโดยอัตโนมัติจากฐานข้อมูลในครั้งแรกที่มีการเข้าถึงคุณสมบัติที่อ้างถึงเอนทิตี / เอนทิตี การโหลดแบบขี้เกียจหมายถึงการโหลดข้อมูลที่เกี่ยวข้องล่าช้าจนกว่าคุณจะร้องขอโดยเฉพาะ

  • เมื่อใช้ประเภทเอนทิตี POCO การโหลดแบบขี้เกียจทำได้โดยการสร้างอินสแตนซ์ของประเภทพร็อกซีที่ได้รับจากนั้นแทนที่คุณสมบัติเสมือนเพื่อเพิ่มเบ็ดการโหลด

  • การโหลดขี้เกียจเป็นค่าเริ่มต้น

  • หากคุณออกจากการกำหนดค่าเริ่มต้นและไม่ได้บอก Entity Framework อย่างชัดเจนในแบบสอบถามของคุณว่าคุณต้องการอย่างอื่นนอกเหนือจากการโหลดแบบขี้เกียจการโหลดแบบขี้เกียจคือสิ่งที่คุณจะได้รับ

  • ตัวอย่างเช่นเมื่อใช้คลาสเอนทิตี Student การลงทะเบียนที่เกี่ยวข้องจะถูกโหลดในครั้งแรกที่เข้าถึงคุณสมบัติการนำทางการลงทะเบียน

  • คุณสมบัติการนำทางควรกำหนดเป็นสาธารณะเสมือน บริบทจะNOT ขี้เกียจโหลดถ้าคุณสมบัติไม่ได้กำหนดเป็นเสมือน

ต่อไปนี้เป็นคลาสนักเรียนที่มีคุณสมบัติการนำทางของการลงทะเบียน

public partial class Student {

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

มาดูตัวอย่างง่ายๆในการโหลดรายชื่อนักเรียนจากฐานข้อมูลก่อนจากนั้นจะโหลดการลงทะเบียนของนักเรียนคนใดคนหนึ่งเมื่อใดก็ตามที่คุณต้องการ

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

เมื่อโค้ดด้านบนถูกคอมไพล์และดำเนินการคุณจะได้รับผลลัพธ์ต่อไปนี้

ID: 1, Name: Ali 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

ปิด Lazy Loading

การโหลดแบบขี้เกียจและการทำให้เป็นอนุกรมไม่เข้ากันและหากคุณไม่ระมัดระวังคุณสามารถค้นหาฐานข้อมูลทั้งหมดของคุณได้เพียงเพราะเปิดใช้งานการโหลดแบบขี้เกียจ เป็นแนวทางปฏิบัติที่ดีในการปิดการโหลดแบบขี้เกียจก่อนที่คุณจะจัดลำดับเอนทิตี

การปิดสำหรับคุณสมบัติการนำทางเฉพาะ

สามารถปิดการโหลดคอลเล็กชันการลงทะเบียนได้โดยการทำให้คุณสมบัติการลงทะเบียนไม่ใช่เสมือนดังที่แสดงในตัวอย่างต่อไปนี้

public partial class Student { 

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

ปิดสำหรับเอนทิตีทั้งหมด

Lazy loading สามารถปิดได้สำหรับเอนทิตีทั้งหมดในบริบทโดยตั้งค่าแฟล็กบนคุณสมบัติ Configuration เป็น false ดังที่แสดงในตัวอย่างต่อไปนี้

public partial class UniContextEntities : DbContext { 

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

หลังจากปิดการโหลดแบบขี้เกียจตอนนี้เมื่อคุณเรียกใช้ตัวอย่างด้านบนอีกครั้งคุณจะเห็นว่าการลงทะเบียนไม่ได้โหลดและดึงเฉพาะข้อมูลนักเรียนเท่านั้น

ID: 1, Name: Ali 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 Olivetto

เราขอแนะนำให้คุณดำเนินการตามตัวอย่างข้างต้นในลักษณะทีละขั้นตอนเพื่อความเข้าใจที่ดีขึ้น