Criando um repositório genérico para Entity Framework

Criando um repositório genérico para Entity Framework

Irei demonstrar aqui uma forma bem simples e rápida para implementarmos um repositório genérico com Entity Framework. A ideia de implementação será a mesma utilizada com Linq to SQL, ou seja, nosso repositório será responsável por realizar apenas quatro operações: Selecionar os dados, salvar, apagar e atualizar.

Vamos primeiramente criar uma interface para o repositório:

01.public interface IRepositorio
02.{
03.    void Atualiza();
04. 
05.    void Apaga<TEntidade>(TEntidade entidade) where TEntidade : class;
06. 
07.    void Salva<TEntidade>(TEntidade entidade) where TEntidade : class;
08. 
09.    IQueryable<TEntidade> Seleciona<TEntidade>() where TEntidade : class;
10.}

Agora vamos ao principal, a implementação de fato dos métodos:

01.public class Repositorio : IRepositorio
02.{
03.    private readonly DB _db;
04. 
05.    public Repositorio(DB db)
06.    {
07.        _db = db;
08.    }
09. 
10.    public void Atualiza()
11.    {
12.        _db.SaveChanges();
13.    }
14. 
15.    public void Apaga<TEntidade>(TEntidade entidade) where TEntidade : class
16.    {
17.        _db.DeleteObject(entidade);
18.        Atualiza();
19.    }
20. 
21.    public void Salva<TEntidade>(TEntidade entidade) where TEntidade : class
22.    {
23.        _db.AddObject(typeof(TEntidade).Name, entidade);
24.        Atualiza();
25.    }
26. 
27.    public IQueryable<TEntidade> Seleciona<TEntidade>() where TEntidade : class
28.    {
29.        return _db.CreateObjectSet<TEntidade>();
30.    }
31.}

Legal e muito simples não? porém, sei que algumas dúvidas devem estar presentes, vejamos:

 

Perguntas/Respostas

1-) Em que momento é realizado o new no objeto DB ? Exemplo: _db = new DB();
Resposta: Para o exemplo utilizei IoC - Injeção de Dependência.

2-) Não estaria faltando um método para permitir a seleção de apenas um registro no DB?
Resposta: Acredito que não. Isso pelo fato de que nosso método Seleciona retorna um IQueryable, desta forma, auxiliado pelo "Deferred Loading" nossa query ainda não foi executada de fato no DB até que haja uma iteração concréta na mesma. Desta forma podemos realizar uma seleção única posteriormente.

3-) Mas seria errado criar o método para seleção única no repositório ?
Resposta: Não. Seria uma implementação bem simples por sinal, veja:

1.public TEntidade Seleciona<TEntidade>(string whereLinq) where TEntidade : class
2.{
3.    return _db.CreateObjectSet<TEntidade>().Where(whereLinq).FirstOrDefault();
4.}

Antes da próxima pergunta já adianto, sim, estou utilizando Dynamic Linq para efetuar nosso where, mas nada o impede de utilizar outros recursos como Predicated Builder, etc!

4-) E como seria realizado um Update de algum regitro no DB?
Resposta: Irei demonstrar um Update de uma forma bem rápida e simples, porém, a ideia é a mesma para objetos mais complexos. Veja:

01.public class Service : IService
02.{
03.    private readonly Repositorio _repositorio;
04. 
05.    public Service(Repositorio repositorio)
06.    {
07.        _repositorio = repositorio;
08.    }
09. 
10.    public void TesteAtualizaRegistro()
11.    {
12.        //Seleciona o Produto que possua código igual a 1
13.        var p = _repositorio.Seleciona<Produto>("cod = 1");
14. 
15.        //Seta os novos valores para as propriedades nome e valor
16.        p.nome = "Nome Atualizado";
17.        p.valor = 130;
18. 
19.        //Chama método Atualiza no repositório, aqui é efetuado o SaveChanges()
20.        _repositorio.Atualiza();
21.    }
22.}

Deu para captar? atente-se que para a atualização funcionar, o método Atualiza() deve ser chamado após os novos valores serem setados. Simples assim!

Considerações Finais

O uso de um repositório genérico ajuda e muito a padronização do nosso código, além de facilitar as principais operações e viabiliza-las em um único lugar. Considere aprender e aplicar outros conceitos e tecnologias, como por exemplo: IoC, UoW, Dynamic Linq, AutoMapper, Predicated Builder, etc. Dúvidas, sugestões, críticas serão muito bem vindas!


Rafael Zaccanini
MTAC – Microsoft Technical Audience Contributor

Blog: http://www.rafaelzaccanini.net   
Twitter: 
@rafaelzaccanini   
Facebook: http://www.facebook.com/RafaelZaccaniniNet   

Classificar por: Data da Publicação | Mais Recente | Mais Úteis
Comentários
Página 1 de 1 (2 itens)