Entity Framework - Chargement différé

Le chargement différé est le processus par lequel une entité ou une collection d'entités est automatiquement chargée à partir de la base de données lors du premier accès à une propriété faisant référence à l'entité / aux entités. Le chargement différé signifie retarder le chargement des données associées, jusqu'à ce que vous en ayez spécifiquement la demande.

  • Lors de l'utilisation de types d'entités POCO, le chargement différé est obtenu en créant des instances de types de proxy dérivés, puis en remplaçant les propriétés virtuelles pour ajouter le hook de chargement.

  • Le chargement paresseux est à peu près la valeur par défaut.

  • Si vous laissez la configuration par défaut et que vous n'indiquez pas explicitement à Entity Framework dans votre requête que vous voulez autre chose que le chargement différé, alors le chargement différé est ce que vous obtiendrez.

  • Par exemple, lors de l'utilisation de la classe d'entité Student, les inscriptions associées seront chargées lors du premier accès à la propriété de navigation Inscriptions.

  • La propriété de navigation doit être définie comme publique, virtuelle. Le contexte vaNOT effectuez un chargement différé si la propriété n'est pas définie comme virtuelle.

Voici une classe Student qui contient la propriété de navigation des inscriptions.

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

Jetons un coup d'œil à un exemple simple dans lequel la liste des étudiants est d'abord chargée à partir de la base de données, puis elle chargera les inscriptions d'un étudiant en particulier chaque fois que vous en aurez besoin.

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

Lorsque le code ci-dessus est compilé et exécuté, vous recevrez la sortie suivante.

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

Désactiver le chargement différé

Le chargement paresseux et la sérialisation ne se mélangent pas bien, et si vous ne faites pas attention, vous pouvez finir par interroger toute votre base de données simplement parce que le chargement paresseux est activé. Il est recommandé de désactiver le chargement différé avant de sérialiser une entité.

Désactivation pour des propriétés de navigation spécifiques

Le chargement différé de la collection Enrollments peut être désactivé en rendant la propriété Enrollments non virtuelle, comme illustré dans l'exemple suivant.

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

Désactiver pour toutes les entités

Le chargement différé peut être désactivé pour toutes les entités du contexte en définissant un indicateur de la propriété Configuration sur false, comme illustré dans l'exemple suivant.

public partial class UniContextEntities : DbContext { 

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

Après avoir désactivé le chargement différé, maintenant, lorsque vous exécutez à nouveau l'exemple ci-dessus, vous verrez que les inscriptions ne sont pas chargées et que seules les données des étudiants sont récupérées.

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

Nous vous recommandons d'exécuter l'exemple ci-dessus étape par étape pour une meilleure compréhension.