.NET

21 jan, 2014

Separando suas classes de modelo da sua camada de acesso a dados com Entity Framework Code First

Publicidade

Normalmente nos tutoriais básicos de Entity Framework deixamos tudo da forma mais simples possível, tentando mostrar somente a parte em que o EF funciona, ignorando o design de aplicação. Não sei dizer se é por preguiça (nossa, de quem escreve) ou por achar na hora que quem ler pode acabar se perdendo ou nem se importando.

Hoje eu vejo muitas (muitas mesmo) perguntas no fórum da MSDN ou no StackOverflow em que a pessoa que pergunta entende que Asp.Net MVC e Entity Framework são a mesma coisa, e isso não é agradável de se ver. Se eu tento, antes de responder a pergunta, explicar a diferença posso ser tachada de chata.

Há semanas o meu amigo Elemar Junior escreveu em seu blog sobre acoplamento evidente em aplicações em 3 camadas e em seu texto comparou os exemplos básicos de Entity Framework em que a camada de interface trabalha direto com domínio e com a camada de dados e concordo que é um exemplo ruim, pois vejo uma quantidade exorbitante de pessoas que pegam dos exemplos e começam a trabalhar dessa forma sempre.

Quando você, por exemplo, mapear sua base de dados para um EDM e começa nas páginas web, por exemplo (porque podia ser um winforms, wpf whatever) e começa a fazer manipulações de contexto, adicionando items, buscando, etc, acada seguindo o modelo que o Elemar citou como errado.

Algumas pessoas me pediram para escrever sobre como usar alguns patterns em conjunto com o Entity Framework e, pense, não era necessário criar um exemplo assim se as pessoas soubessem separar as clases de modelo e as entidades, da camada de acceso a dados. Esse é básico. Não precisaria explicar como aplicar um pattern que nem diz respeito a acesso a dados com Entity Framework se as pessoas não tivessem tão enraizadas a ideia de modelos já dentro da DAL.

Outra coisa que já vi: quem pegasse um EDM e jogasse em um projeto que chamou de, por exemplo, ‘DataAccess”e mesmo assim ia chamando o EDM diretamente em sua UI Layer sem nada no meio. Não é nem agradável de se ver isso. Se um dia você mudar algo no seu EDM teria que mudar a UI Layer também só porque ela está com o EDM enraizado nela?

Suas classes de modelo não precisam estar na camada de acesso a dados

Esse é o primeiro erro que eu vejo. Se você deixa suas models junto de sua implementação da DbContext vai acabar deixando as suas models junto da camada de acceso a dados. Você realmente não precisa fazer dessa forma.

Veja, você pode muito bem manter as classes em um projeto a parte. Em um de camada de acesso a dados (sou só de contexto) você pode referenciar esse projeto. Mesmo que você esteja utilizando Code First com a ideia de Database First você pode fazer isso. Uma vez que tenha usado Entity Framework Power Tools, você pode mapear sua base já existente.

Vejamos: eu criei uma solution chamada SchoolArch. Dentro criei uma pasta Domain onde criei um projeto do tipo Libary com o nome Model. Agora eu vou usar o EF Power Tools para gerar as classes de modelo baseadas no banco de dados já existente. Para esse projeto eu criei um banco de dados do tipo Sql Compact com o modelo School criado pela comunidade na MSDN para servir de alternativa para o AdventuresWork.

Models criadas pelo EF Power Tools
Models criadas pelo EF Power Tools

Pois bem, ele criou no meu projeto uma pasta chamada Models com as classes de modelo e uma pasta chamada Mapping dentro da Models, com as classes de configuração utilizando Fluent API.

Como vê, assim que usamos o EF Power Tools ele já separa mapeamento de modelo. Essas classes de mapeamento herdam da EntityTypeConfiguration fazendo com que tenhamos classes especificas de configuração para cada entidade, tornando o nosso builder de modelos mais uniforme, limpo e contendo todas as configurações encapsuladas.

Uma coisa que eu gosto de fazer é pegar as classes de mapeamento e a classe de contexto e trazer para outro projeto, separado. Fazia isso por intuição, até ver alguns outros textos e projetos no github seguindo a mesma ideia.

Se você está criando suas classes de modelo do zero já considere separar dessa forma, separando o contexto, mapeamento e propriedades no banco em um projeto separado.

Agora você possui seus modelos sozinhos, limpos e livres. Mas ainda estão anêmicos. Aí você coloca sua lógica para cada um deles. O importante é que não é preciso misturar tudo. Agora, se você mudar algo no banco de dados, por exemplo, mudar o nome de uma coluna (não sei, vai que…) você pode mudar no mapeamento, lá naquela DAL. Um ponto a favor de Code First, alias, não ter o EDM.

A partir daí já fica mais fácil imaginar como você vai construir sua camada de acceso a dados, né? Quem quiser ver um exemplo mais completo pode ver o exemplo do meu mestre Fernando Henrique, o PantheonRepository no Github.

Note que, apesar de citado nos comentários do post citado do Elemar, eu nem usei de DI, nem nada… E já foi o principio para você não me enfiar uma instância de DbContext dentro da sua UI Layer.

Bom, agora você pode deixar suas classes separadinhas. Por hoje é só, com o passar do tempo veremos mais sobre padrões para você construir sua camada de acesso a dados.

Fonte: MayogaX Dev Blog