Entity Framework: Preguiça ou Solução?

O Entity Framework gera muita controvérsia por possuir mais de uma forma de utilizá-lo. Mas seria preguiça do desenvolvedor em escrever as consultas ou realmente é uma solução definitiva para acesso a banco de dados?

Entity Framework: Preguiça ou Solução?

O assunto Entity Framework sempre vem a tona quando realizo mentorias e treinamentos. Sempre me perguntam: E o EF? É bom? Qual melhor forma de usar? Code First? Database First? Blá blá blá…

Nesse artigo, começo compartilhando minha experiência com essa tecnologia, depois passo a analisar sua aderência com Design Patterns, e por fim, faço algumas observações e sugestões caso você opte por usar o EF.

Então, sem evitar a fadiga, vamos ao que interessa!

DESIGN PATTERNS Programação no Mundo Real


#Entity Framework

Se você caiu de paraquedas e não sabe o que é Entity Framework, se liga:

EF é uma biblioteca/DLL que pode ser baixada através do NuGet e tem objetivo de ajudar no acesso a banco de dados para realização de consultas e gravação de dados.

Esse tipo de software é chamado ORM (mapeador relacional de objetos) e existem vários no mercado, como por exemplo NHibernate e Dapper.

O EF funciona com diversos tipos de banco de dados, e assim como todo e qualquer ORM, facilita o acesso ao banco de dados, mapeando suas tabelas e permitindo a manipulação dos registros sem muito esforço.

O que diferencia o EF de outros ORM é o uso do LINQ para montagem de queries no próprio C#.


#EF e eu

Nossa equipe recebeu um projeto para desenvolver um portal de divulgação de cupons de desconto. E para ele, decidimos usar tecnologias de ponta unindo o útil ao agradável, ou seja, aprendendo e evoluindo tecnicamente.

Pois bem, seguindo nessa linha optamos por desenvolver com conceitos de Single Page Application para frontend usando AngularJS, Bootstrap para o visual e Entity Framework para acesso a dados.

Bom, você já reparou com esse projeto de cupons foi desenvolvido hà muito tempo.

Eu não lembro qual era a versão do EF que usamos e menos ainda se possuia os modos Code First e Model First.

O que posso dizer com muita franqueza, é que tivemos muitas dificuldades em criar aquelas Expressions mirabolantes no LINQ. E pior ainda, tivemos muitos problemas de performance.

Ao usar o EF com essas Expressions, por de trás dos panos, o EF monta um comando SQL executando-o no banco de dados correspondente.

Dá uma olhada no exemplo abaixo:

using (var db = new BloggingContext())
{
    var blogs = db.Blogs
        .Where(b => b.Rating > 3)
        .OrderBy(b => b.Url)
        .ToList();
}

Vai gerar algo do tipo:

SELECT    * 
FROM      Blogs 
WHERE     Rating > 3
ORDER BY  Url

Lindo não? Nesse momento você está pensando: “Nossa isso vai me ajudar muito, facilita muito!” A resposta é: Sim, não e depende.

Expressions assim são simples, não demandam muito esforço e entendimento.

Mas imagina que você tem comandos SQL mais complexos como GROUP BY, SUM e SUB SELECT, como fazer isso no C#?

           using (var ctx = new PrimayEntityContext())
           {
                var query = from oferta in ctx.OfertaEmailSet
                            join la in ctx.LojaAfiliacaoSet on oferta.CodigoLojaAfiliacao equals la.Codigo
                            join loja in ctx.LojaSet on la.CodigoLoja equals loja.Codigo
                            where la.CodStatus == 1
                            group oferta by loja.Codigo into groups
                            select groups.FirstOrDefault();

                var query2 = from oferta in query
                             join la in ctx.LojaAfiliacaoSet on oferta.CodigoLojaAfiliacao equals la.Codigo
                             join loja in ctx.LojaSet on la.CodigoLoja equals loja.Codigo
                             where la.CodStatus == 1
                             select new
                             {
                                 HtmlOriginal = oferta.HtmlOriginal,
                                 HtmlAlterado = oferta.HtmlAlterado,
                                 VigenciaDe = oferta.VigenciaDe,
                                 VigenciaAte = oferta.VigenciaAte,
                                 Codigo = oferta.Codigo,
                                 CodigoLojaAfiliacao = oferta.CodigoLojaAfiliacao
                             };

                if (pag.HasValue
                    && top.HasValue
                    && !pag.Value.Equals(0)
                    && !top.Value.Equals(0))
                {
                    query2 = query2.Skip(pag.Value * top.Value);
                }

                if (top.HasValue)
                {
                    query2 = query2.Take(top.Value);
                }

                query2
                    .ToList()
                    .ForEach(x => lista.Add(new Models.Queries.OfertaEmail()
                    {
                        Codigo = x.Codigo,
                        HtmlOriginal = x.HtmlOriginal,
                        HtmlAlterado = x.HtmlAlterado,
                        VigenciaDe = x.VigenciaDe,
                        VigenciaAte = x.VigenciaAte,
                        CodigoLojaAfiliacao = x.CodigoLojaAfiliacao
                    }));
            }

Na boa…. não dá. Deixa a fadiga de lado, cria aí uma Stored Procedure ou monta essa query na mão!

Nesse momento você deve estar xigando e/ou falando mal do código fonte acima.

Eu não tenho medo do passado, ninguém é perfeito. Estamos falando de algo desenvolvido à quase 10 anos. Atualmente existem diversos blogs e conteúdo a respeito, mas no começo éramos nós e Deus.

O ponto que quero chegar é, além da dificuldade nas expressions, o Entity Framework gerava um código SQL absurdo que impactava diretamente na performance da aplicação.

Eu olhava pra aquilo, automaticamente me vinham na memória aquelas malditas Regular Expressions!

Além disso, tem também a questão da nomenclatura. Quando as propriedades e classes C# tem os mesmos nomes das tabelas do banco de dados tudo bem, mas quando são diferentes é necessário realizar mapeamentos “DE/PARA” e ai começa enrolar o meio de campo.

Bom, vamos seguindo.


#Code First, Database First e Repository

Com modo Code First, você cria as classes/propriedades no C# e gera as tabelas/colunas no banco de dados automaticamente.

Já no modo Database First, você tem um banco de dados e gera as classes/propriedades no C# a partir dele.

E também tem o modo Braddock, onde você consegue fazer tudo na mão, configurando os relacionamentos e mapeamentos C#/Database sem gerar nada.

Referente ao Repository Pattern junto com Entity Framework, é viável tecnicamente mas eu não faria por deixar a aplicação ainda mais complexa, pois o EF já implementa o Repository Pattern e Unit of Work.

Em uma época remota, antes desses ORM, desenvolvemos geradores de classe de acesso a dados baseado no schema de banco de dados SQL, que transformou em um caso de sucesso até para a Microsoft.


#Considerações

Eu não estou falando para você usar ou não usar o Entity Framework, ou se ele é bom ou não.

Não é só porque a Microsoft e alguns de seus evangelistas te empurram uma tecnologia, que você terá que usar. Vale a pena pesquisar e criar provas de conceito que possibilitem uma análise de viabilidade ao seu problema.

O que posso garantir é, no mercado o uso de EF é mais utilizado em operações de escrita e não consulta. Se eu usasse EF, usaria apenas para escrita.

Respondendo a pergunta no título desse artigo, Preguiça ou Solução? Eu diria “é uma solução preguiçosa”, fui…

Obrigado e até a próxima.

Para saber mais:

@mlbors repository-pattern-ef | imasters.com.br | Code First – Database First | Curso Baltieri | Renato Groffe

Sobre o Autor:
Trabalha como arquiteto de soluções e desenvolvedor, tem mais de 18 anos de experiência em desenvolvimento de software em diversas plataformas sendo mais de 16 anos somente para o mercado de seguros.
Revisado por:
Paulistano, 21 anos apaixonado por tecnologia, trabalho com desenvolvimento de software atuando com .NET / Xamarin / AngularJS / ASP.NET CORE / MVC.