Posts Tagged ‘lazy loading’

Usando Lazy Loading e Eager Loading no Entity Framework 4.0

agosto 15, 2010

  

Lazy Loading e Eager Loading são formas de carregamento de dados. 

Lazy Loading 

Com o Lazy Loading habilitado as entidades relacionadas são carregadas quando as mesmas são acessadas pela Navigation Property

Vejamos a estrutura abaixo: 

  

Temos três entidades, Cliente, Telefone e Extrato. Se o Lazy Loading estiver habilitado, quando carregarmos a entidade Cliente todas as entidades relacionadas (Telefone e Extrato) não serão carregadas. 

Se usarmos o Entity Framework para gerar a camada de objetos, o Lazy Loading vem habilitado por default

Para habilitar ou desabilitar o Lazy Loading basta configurarmos a propriedade ContextOptions.LazyLoadingEnable do contexto. 

Para ficar mais claro, vamos carregar a entidade Cliente com o Lazy Loading habilitado e desabilitado. 

using (DbTesteContainer context = new DbTesteContainer())
{
    context.ContextOptions.LazyLoadingEnabled = true;

    var clientes = context.Cliente;

    foreach (var cliente in clientes)
    {
        Console.WriteLine("Cliente: {0}", cliente.Nome);

        foreach (var telefone in cliente.Telefone)
        {
            Console.WriteLine("Telefone: {0} - {1}",
                telefone.DDD, telefone.Numero);
        }
    }
}

Com o Lazy Loading habilitado conseguimos percorrer por todas as entidades relacionadas sem problemas. 

 

Desabilitando o Lazy Loading, quando acessarmos a entidade Telefone através da Navigation Property não teremos sucesso, pois a propriedade Telefone está nula. 

  

Abaixo outro exemplo. 

using (DbTesteContainer context = new DbTesteContainer())
{
    context.ContextOptions.LazyLoadingEnabled =
        false;

    var cliente = context.Cliente.FirstOrDefault();

    try
    {
        Console.WriteLine(
            cliente.Telefone.FirstOrDefault().Numero);
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

Qual o resultado?

Uma exceção do tipo NullReferenceException é disparada.

 

 

Eager Loading

Eager Loading é o oposto do Lazy Loading, ou seja, quando carregamos uma entidade podemos carregar todas (ou algumas) entidades relacionadas ao mesmo tempo através da Navigation Property. Existem duas formas de se fazer isso, a forma implícita e a forma explícita. 

Forma Implícita 

Na forma implícita usamos o método Include

using (DbTesteContainer context = new DbTesteContainer())
{
    context.ContextOptions.LazyLoadingEnabled =
        false;

    var cliente =
        context.Cliente.Include("Telefone").FirstOrDefault();

    try
    {
        Console.WriteLine(
            cliente.Telefone.FirstOrDefault().Numero);
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.GetBaseException());
    }
}

  

Forma Explícita 

Na forma explícita usamos o método LoadProperty do contexto. 

using (DbTesteContainer context = new DbTesteContainer())
{
    context.ContextOptions.LazyLoadingEnabled =
        false;

    Cliente cliente = context.Cliente.FirstOrDefault();
    context.LoadProperty(cliente, "Telefone");

    try
    {
        Console.WriteLine(
            cliente.Telefone.FirstOrDefault().Numero);
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.GetBaseException());
    }
}

  

O problema dos métodos Include e LoadProperty é o fato de não serem fortemente tipados. Mas uma solução é usarmos o método LoadProperty<TEntity>(TEntity entity, Expression<Func<TEntity, object>> selector)

Cliente cliente = context.Cliente.FirstOrDefault();
context.LoadProperty<Cliente>(cliente, c => c.Telefone);
Anúncios