Alguns tipos de erros que encontramos durante o desenvolvimento de um projeto são irritantes, principalmente aqueles que acontecem “silenciosamente” sem deixar muitas pistas sobre o que está acontecendo. Em geral isso acontece quando o desenvolvedor deixa passar alguma regra de maneira despercebida e acaba correndo atrás do próprio rabo.

Outro dia estava elaborando um exemplo usando Entity Framework (EF) e tudo pareceu estar funcionando bem. Criei as entidades, configurei o EF usando fluent API, incluí novos objetos no banco de dados e confirmei tudo por meio de queries. Ao tentar recuperar a entidade salva eu me deparei com um problema de NullReferenceException quando tentei acessar uma propriedade de navegação que deveria ser preenchida via lazy loading.

Sabendo que este tipo de problema acontece normalmente quando o Lazy Loading está desabilitado, logo fui verificar se havia desativado a funcionalidade por engano. Tudo parecia correto, mas mesmo assim  deixei explícita toda a configuração que deveria ser padrão:

public AppDbContext()
{
    Configuration.LazyLoadingEnabled = true;
    Configuration.ProxyCreationEnabled = true;
}

Chequei se as propriedades estavam marcadas com o modificador virtual e se eram públicas. Novamente tudo correto.

public virtual TelefoneFixo TelefoneFixo { get; set; }

Após alguma pesquisa cheguei em uma página do MSDN que, embora esteja dizendo que é um pre-release, me trouxe a luz sobre o que estava acontecendo: minhas classes não estavam públicas! Pior é que já passei por esse problema antes, mas acabei deixando passar este detalhe extremamente importante.

Claro que tudo me pareceu óbvio depois que descobri o problema, afinal de contas o EF usa proxies (reflection) para poder injetar o comportamento de lazy loading e, para isso, a classe deve ser pública.

Checklist para Lazy Load:

  • Obviamente o lazy loading deve estar habilitado (Configuration.LazyLoadingEnabled = true;)
  • A criação de classes proxies deve estar habilitada (Configuration.ProxyCreationEnabled = true;)
  • As classes devem ser públicas (public)
  • As classes não podem ser modificadas com sealed ou abstract
  • As classes devem conter um método sem parâmetros que seja público (public) ou protegido (protected)
  • A propriedade de navegação deve ser pública (public) e virtual e não pode ter o get modificado com sealed

 

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *