EF 6 - Aplicação em Camadas - Entendendo o código do repositório - IV
Neste artigo vamos continuar o nosso exemplo anterior explicando em detalhes a implementação da interface IRepositorio. |
Entendendo o código usado na implementação do repositório
No artigo anterior definimos a interface do nosso repositório e fizemos sua implementação na classe Repositorio.
O que é uma interface ? Uma interface, no paradigma da orientação a objetos, é um tipo de classe que contém apenas as assinaturas de métodos, propriedades, eventos e indexadores. A implementação dos membros é feita por uma classe concreta ou struct que implementa a interface. |
Segue abaixo novamente o código da classe Repositorio implementando a interface IRepositorio e a interface IDisposable:
using
System; using System.Collections.Generic; using System.Data.Entity; using System.Linq; using System.Linq.Expressions;
namespace
DAL
protected Repositorio()
public IQueryable<T> Get(Expression<Func<T, bool>> predicate)
public T Find(params object[] key)
public T First(Expression<Func<T, bool>> predicate)
public void Adicionar(T entity)
public void Atualizar(T entity)
public void Deletar(Func<T, bool> predicate)
public void Commit()
public void Dispose() |
Agora vamos detalhar e entender cada método implementado.
1- private
CadastroEntities Context;
protected Repositorio() |
Aqui estamos referenciando o contexto representando por CadastroEntities na variável Context e criando uma nova instância do contexto. Tudo depende do contexto e vamos usar sua referência em todos os métodos para acessar as entidades no Entity Data Model.
2-
public IQueryable<T> GetTodos() { return Context.Set<T>(); } |
O método GetTodos() recebe uma entidade (uma classe) e retorna um IQueryable, ou seja uma lista completa das entidades. (Aqui o método Set<T> do contexto retorna uma instância instância DbSet<T> para o acesso a entidades de determinado tipo no contexto.)
Para entender melhor o IQueryable veja o meu artigo : .NET - Comparando IEnumerable com IQueryable.
3- public IQueryable<T> Get(Expression<Func<T, bool>> predicate) { return return Context.Set<T>().Where(predicate); } |
O método Get() usa um delegate Func<> como parâmetro de entrada, onde será usada uma expressão lambda (Ex: p => p.EmpregadoId == ID) como critério, e, um predicate para validar o critério usando a cláusula Where. O retorno será uma lista IQueryable.
Para entender melhor o delegate Func<> veja o meu artigo: C# - Apresentando o delegate Func
4- public T Find(params object[] key) { return Context.Set<T>().Find(key); } |
O método Find() realiza uma busca pela chave primária. O parâmetro de entrada é um array de objetos. O método localiza uma entidade com os valores indicados na chave primária.
Se a entidade existir no contexto, então ela é devolvida imediatamente. Caso contrário, é feita uma solicitação à base. Se nenhuma entidade for encontrada no contexto ou na base, então é retornado null.
5- public T First(Expression<Func<T, bool>> predicate) { return Context.Set<T>().Where(predicate).FirstOrDefault(); } |
O método First() usa uma expressão com o delegate Func<> como entrada, aqui usaremos uma expressão lambda que será validada pelo predicate usando a cláusula Where. FirstOrDefault() garante que será retornado o primeiro elemento da seqüência que satisfaça a condição definida na expressão lambda ou o valor padrão se nenhum elemento for encontrado.
6- public void Adicionar(T entity) { Context.Set<T>().Add(entity); } |
O método Adicionar() recebe uma entidade e usando o método Add() do contexto inclui a entidade no contexto. (Nos bastidores o EF cria uma instrução SQL Insert)
Você pode incluir diversas entidades de uma vez. Apenas lembre-se que neste cenário estamos trabalhando na memória. Para persistir no banco de dados devemos o método SaveChanges().
7- public void Atualizar(T entity) { Context.Entry(entity).State = EntityState.Modified; } |
O método Atualizar() recebe uma entidade e define o seu EntityState como Modified informando ao contexto que a entidade foi alterada.
O estado da entidade é uma enumeração do tipo System.Data.EntityState que declara os seguintes valores:
O contexto não
só trata a referência para todos os objetos recuperados do banco de dados, mas
também detém os estados da entidade e mantém as modificações feitas nas
propriedades da entidade. Este recurso é conhecido como controle de alterações
ou Change Tracking.
A mudança no estado da entidade de Unchanged para o estado Modified
é o único estado que é feito automaticamente pelo contexto.
8- public void Deletar(Func<T, bool> predicate) { Context.Set<T>() .Where(predicate).ToList() .ForEach(del => Context.Set<T>().Remove(del)); } |
O método Deletar() usa como parâmetro de entrada um delegate Func<>, onde será usada uma expressão lambda, que será validada pelo predicate usando a cláusula Where(). Note que estamos usando o método Remove do contexto com uma expressão lambda (del => Context.Set<T>().Remove(del)) em um .ForEach(), o efeito disso é que ele irá varrer a lista retornada e irá remover todos os itens que atendem ao critério definido para remoção.
9- public void Commit() { Context.SaveChanges(); } |
O método Commit() é um dos mais importantes porque ele usa o método SaveChanges() do contexto para persistir no banco de dados as inclusões, exclusões e alterações feitas no contexto que ainda estão na memória.
Quando você trabalha com o Contexto e seus métodos esta trabalhando na memória. O método SaveChanges() efetiva todas as operações gravando-as no banco de dados. Assim quando você trabalha na memória pode ter muitas entidades em diversos estados, e quando usa o SaveChanges() elas serão efetivamente gravadas no banco de dados.
10- public void Dispose() { if (Context != null) { Context.Dispose(); } GC.SuppressFinalize(this); } |
O método Dispose() implementa a interface IDisposable e verifica se o contexto não é nulo para liberar recursos usados
Os conceitos sobre Delegates (Func, Action, Predicate) e Expressões Lambdas são a base para entender o código usado na implementação feita.
Na próxima parte do artigo vamos definir a nossa camada de negócios.
Porque não vos fizemos saber a virtude e a vinda de nosso Senhor Jesus Cristo, seguindo fábulas artificialmente compostas; mas nós mesmos vimos a sua majestade. (2 Pedro 1:16)
Veja os
Destaques e novidades do SUPER DVD Visual Basic
(sempre atualizado) : clique e confira !
Quer migrar para o VB .NET ?
Quer aprender C# ??
Quer aprender os conceitos da Programação Orientada a objetos ? Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ? |
Gostou ? Compartilhe no Facebook Compartilhe no Twitter
Referências: