Entity Framework - ładowanie z opóźnieniem
Ładowanie z opóźnieniem to proces, w którym jednostka lub kolekcja jednostek jest automatycznie ładowana z bazy danych przy pierwszym dostępie do właściwości odwołującej się do jednostki / jednostek. Leniwe ładowanie oznacza opóźnianie wczytywania powiązanych danych, dopóki nie zażądasz tego.
- W przypadku korzystania z typów jednostek POCO leniwe ładowanie uzyskuje się przez utworzenie wystąpień pochodnych typów proxy, a następnie przesłanianie właściwości wirtualnych w celu dodania zaczepu ładowania. 
- Leniwe ładowanie jest prawie domyślne. 
- Jeśli opuścisz domyślną konfigurację i nie powiesz wyraźnie Entity Framework w zapytaniu, że chcesz coś innego niż ładowanie z opóźnieniem, otrzymasz ładowanie z opóźnieniem. 
- Na przykład podczas korzystania z klasy jednostki Student powiązane rejestracje zostaną załadowane przy pierwszym dostępie do właściwości nawigacji Enrollments. 
- Właściwość nawigacji powinna być zdefiniowana jako publiczna, wirtualna. Kontekst będzieNOT wykonaj ładowanie z opóźnieniem, jeśli właściwość nie jest zdefiniowana jako wirtualna. 
Poniżej znajduje się klasa Student, która zawiera właściwość nawigacji Enrollments.
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; }
}Przyjrzyjmy się prostemu przykładowi, w którym lista studentów jest najpierw ładowana z bazy danych, a następnie wczytuje zapisy konkretnego ucznia, kiedy tego potrzebujesz.
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();
      }
   }
}Gdy powyższy kod zostanie skompilowany i wykonany, otrzymasz następujące dane wyjściowe.
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: 3141Wyłącz leniwe ładowanie
Leniwe ładowanie i serializacja nie mieszają się dobrze, a jeśli nie jesteś ostrożny, możesz zakończyć wykonywanie zapytań dotyczących całej bazy danych tylko dlatego, że jest włączone ładowanie z opóźnieniem. Dobrą praktyką jest wyłączenie leniwego ładowania przed serializacją jednostki.
Wyłączanie określonych właściwości nawigacji
Leniwe ładowanie kolekcji Enrollments można wyłączyć, ustawiając właściwość Enrollments jako niewirtualną, jak pokazano w poniższym przykładzie.
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; } 
}Wyłącz dla wszystkich jednostek
Ładowanie z opóźnieniem można wyłączyć dla wszystkich jednostek w kontekście, ustawiając flagę właściwości Configuration na false, jak pokazano w poniższym przykładzie.
public partial class UniContextEntities : DbContext { 
   public UniContextEntities(): base("name = UniContextEntities") {
      this.Configuration.LazyLoadingEnabled = false;
   }
	
   protected override void OnModelCreating(DbModelBuilder modelBuilder) { 
      throw new UnintentionalCodeFirstException(); 
   } 
}Po wyłączeniu leniwego ładowania, po ponownym uruchomieniu powyższego przykładu zobaczysz, że zapisy nie są ładowane i pobierane są tylko dane uczniów.
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 OlivettoZalecamy wykonanie powyższego przykładu krok po kroku w celu lepszego zrozumienia.