Entity Framework - Lazy Loading

O carregamento lento é o processo pelo qual uma entidade ou coleção de entidades é carregada automaticamente do banco de dados na primeira vez que uma propriedade referente à entidade / entidades é acessada. O carregamento lento significa atrasar o carregamento dos dados relacionados, até que você os solicite especificamente.

  • Ao usar tipos de entidade POCO, o carregamento lento é obtido criando instâncias de tipos de proxy derivados e, em seguida, substituindo as propriedades virtuais para adicionar o gancho de carregamento.

  • O carregamento lento é basicamente o padrão.

  • Se você deixar a configuração padrão e não informar explicitamente ao Entity Framework em sua consulta que deseja algo diferente de carregamento lento, o carregamento lento será o que você obterá.

  • Por exemplo, ao usar a classe de entidade Aluno, os Enrollments relacionados serão carregados na primeira vez que a propriedade de navegação Enrollments for acessada.

  • A propriedade de navegação deve ser definida como pública, virtual. Contexto vaiNOT faça o carregamento lento se a propriedade não estiver definida como virtual.

A seguir está uma classe Student que contém a propriedade de navegação de 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; }
}

Vamos dar uma olhada em um exemplo simples no qual a lista de alunos é carregada do banco de dados primeiro e, em seguida, carregará as matrículas de um aluno específico sempre que você precisar.

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

Quando o código acima for compilado e executado, você receberá a seguinte saída.

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

Desligue o Lazy Loading

O carregamento lento e a serialização não combinam bem e, se você não tomar cuidado, pode acabar consultando todo o banco de dados apenas porque o carregamento lento está ativado. É uma boa prática desativar o carregamento lento antes de serializar uma entidade.

Desativando para propriedades de navegação específicas

O carregamento lento da coleção Enrollments pode ser desativado tornando a propriedade Enrollments não virtual, conforme mostrado no exemplo a seguir.

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

Desligar para todas as entidades

O carregamento lento pode ser desativado para todas as entidades no contexto, definindo um sinalizador na propriedade Configuração como falso, conforme mostrado no exemplo a seguir.

public partial class UniContextEntities : DbContext { 

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

Depois de desligar o carregamento lento, agora, ao executar o exemplo acima novamente, você verá que as inscrições não são carregadas e apenas os dados dos alunos são recuperados.

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

Recomendamos que você execute o exemplo acima passo a passo para melhor compreensão.