Entity Framework - Não cometa esses erros ao utilizar o Entity Framework !!


 Neste artigo vou mostrar alguns dos erros mais comuns cometidos ao se usar o Entity Framework.

O Entity Framework é uma poderosa ferramenta ORM que auxilia o desenvolvimento de aplicações com acesso a dados realizando o mapeamento objeto Relacional.

Como esta integrado à plataforma .NET, usar o Entity Framework é muito fácil e simples, bastando mesmo alguns cliques de mouses para mapear as suas tabelas para entidades.

Mas nem tudo é tão simples como parece. Existem algumas considerações e práticas que devem ser seguidas para obter um melhor rendimento e desempenho da ferramenta.

No menu artigo - Entity Framework - Dicas para melhorar o desempenho - eu apresentei dez dicas que permitem melhorar o desempenho do Entity Framework.

Neste artigo eu apresento cinco erros muito comuns cometidos ao se usar o Entity Framework.

Verifique se você esta cometendo alguns deles:

1 - Esta Instanciando o DbContext muitas vezes ?

Você sabia que existe uma sobrecarga a cada vez que você instancia o objeto DbContext ?

Além disso,  essa prática afeta a utilização do recurso de Cache do Entity Framework e isso se reflete no desempenho da sua aplicação.

Se você esta usando o Entity Framework em uma aplicação ASP  .NET MVC é melhor usar uma única instância do DbContext por toda a duração do Request.

Solução :

2 - Esta rastreando suas entidades quando não precisa disso ?

Quando consultamos entidades usando o entity framework ele guarda as entidades no contexto, realizando o que é conhecido como tracking(rastreamento) das entidades. Ele faz isso para acompanhar o estado das entidades.

Sempre que uma consulta é executada as entidades são carregadas no rastreador de estado dos objetos. Isso é feito para rastrear quais alterações foram feitas no modelo de entidades durante a vida do contexto, de forma que uma chamada ao método SaveChanges irá realizar as consultas SQL requeridas no banco de dados.

Esse é recurso poderoso mas ele adiciona uma sobrecarga considerável que afeta o desempenho das consultas que são rastreadas. As consultas que não são rastreadas tem um desempenho melhor.

Uma solução para isso é usar o método AsNoTracking.

O método de extensão AsNoTracking() retorna uma nova consulta e as entidades retornadas não serão armazenadas em cache pelo contexto (DbContext). Isto significa que o Entity Framework não efetua qualquer processamento ou armazenamento adicional das entidades que são devolvidos pela consulta.

Utilizar o AsNoTracking significa que as entidades serão lidas da origem de dados mas não serão mantidas no contexto.

Nota : Não podemos atualizar estas entidades sem anexá-las ao contexto.

Solução :

Exemplo :

using(Entities context = new Entities())  
{  
    var funcionario = context.Funcionarios.AsNoTracking().ToList();  
}  
3 - Esta tendo o problema Select N + 1 em suas consultas ?

O EF usa por padrão o Lazy loading se você tiver definido os relacionamentos entre as suas entidades usando a palavra-chave virtual. Isto significa que os objetos relacionados, não serão carregados até que eles sejam acessados pela primeira vez.

Isso parece bom à primeira vista, mas pode diminuir o desempenho das suas consultas porque realiza mais idas e vindas no banco de dados podendo causar o problema conhecido como Select N+1 degradando a sua aplicação.
Você pode impedir isso desabilitando o lazy loading (carregamento tardio).

Para mais detalhes leia o meu artigo : Entity Framework - Lazy Loading e o problema Select N+1(Afetando o desempenho da sua aplicação)

Solução :

Exemplo :

using (var context = new BloggingContext()) 
{ 
   //Carrega todos os blogs e posts relacionados
   var blogs = context.Blogs 
               .Include(b => b.Posts) 
               .ToList(); 
}  
4 - Esta incluindo mais campos do que precisa em suas consultas ?

Às vezes, você só precisa exibir um subconjunto de dados a partir de uma entidade. Quando este for o caso, não faz sentido carregar a entidade completa do banco de dados.

Por exemplo, ao listar os clientes que você pode editar ou apagar, você não precisa carregar os campos com detalhes de endereço ou dados pessoais do cliente.

As Consultas Projeção permitem que você selecione alguns campos de uma tabela de banco de dados, projetando os dados em uma entidade mais pequena.

Exemplo :

var _cliente =  (from cli in db.Clientes     
                  select new {
                   cliente. Codigo,
                  cliente.Nome
                 }). ToList (); 
ao invés de :
var _cliente =  (from cli in db.Clientes
                 select cli).ToList();
5 - Esta executando consultas que retornam muitos resultados ?

Dê uma olhada nas consultas abaixo.

O que elas tem de errado ?


  contexto.Posts.ToList().Where(post => post.Ativo);

  contexto.Posts.Where(post => post.Ativo).ToList();

 

Percebeu que elas retornam muitos resultados.

  1. A primeira consulta irá carregar todos os posts porque o método ToList() foi chamado antes do método Where;
  2. A segunda consulta vai carregar menos resultados mas mesmo assim vai carregar mais resultados do que o esperado, pois não houve uma limitação na quantidade de posts ativados a serem retornados;

Solução :

  1. Realize um filtro nas consultas antes de chamar o método ToList()
  2. Limite a quantidade de resultados retornados realizando a paginação do resultado através de um método de extensão. (Na ASP .NET MVC temos o PagedList)

Exemplo :

            using (UnitOfWork uow = new UnitOfWork())
            {
                IEnumerable<Blog> blogs = uow.BlogRepositorio.GetTudo();
                blogs = blogs.OrderByDescending(blog => blog.AtualizadoEm);
                IEnumerable<BlogResumoModel> lista = from blog in blogs
                   select new BlogResumoModel
                   {
                      Id = blog.BlogId,
                      Titulo = blog.Titulo,
                      Resumo = blog.Corpo.Length > 200 ? blog.Corpo.Substring(0, 200) : blog.Corpo,
                      NomeAutor = blog.Usuario.NomeUsuario,
                      ComentariosQuantidade = blog.Comentarios.Count(),
                      CriadoEm = blog.CriadoEm,
                      AtualizadoEm = blog.AtualizadoEm
                   };
                return View(lista.ToList().ToPagedList(pagina ?? 1, 2));
            }

Temos assim 5 dicas práticas que podem melhorar o desempenho de suas consultas com o Entity Framework.

Bom proveito !

Porque a palavra da cruz é loucura para os que perecem; mas para nós, que somos salvos, é o poder de Deus.
Porque está escrito: Destruirei a sabedoria dos sábios, E aniquilarei a inteligência dos inteligentes.
1 Coríntios 1:18,19

Referências:


José Carlos Macoratti