No EF6, como criar um método genérico para obter entidades usando um campo/coluna comum
-
20-12-2019 - |
Pergunta
desculpe se o título não é esclarecedor o suficiente depois de um tempo, não consegui encontrar uma frase para explicar meu problema.
É tipo isso:Estou usando o EF6, abordagem inicial do banco de dados.Todas as minhas entidades possuem um ID e uma propriedade Enabled.Eu tenho o arquivo EDMX no meu DAL e agora preciso projetar a Business Layer (BLL para mim).
Como precisarei validar quais dados vêm do DAL e são visíveis para o resto do aplicativo, decidi criar uma interface para os operadores comuns, criar uma classe base que implemente isso e ter todos os meus provedores de tabelas de banco de dados personalizados\entidades herdar isso.
Se isso não faz sentido, aqui está o que estou fazendo:(Tudo isso está em BLL)
public interface IEntityManager<T> where T : class {
void Add(T e, bool commit=false);
void Delete(T e);
void DeleteByID(int id);
void Update(T e);
IQueryable<T> Search(Expression<Func<T, bool>> predicate);
IQueryable<T> GetAll();
T Get(int id);
}
Agora, a classe base que implementa as operações comuns é esta:(editado para facilitar a leitura e brevidade)
public class EntityManager<TEntity> : IDisposable, IEntityManager<TEntity> where TEntity : class {
private readonly DbContext _ctx;
private readonly DbSet<TEntity> _set;
public EntityManager() {
_ctx = new DomainModelFactory();
_set = _ctx.Set<TEntity>();
}
public void Add(TEntity e) {
_set.AddOrUpdate(e);
}
//other methods here
public TEntity Get(int id) {
return _set.Find(id);
}
}
Para criar gerenciadores que realmente acessem os dados e os tornem utilizáveis em todo o aplicativo, estou planejando fazer algo como:
public class VenueManager: EntityManager<Venue> {
public VenueManager():base() {
}
}
Para a turma que administrará minha entidade Venue.Estou criando classes em vez de usar algo como
var venueManager = new EntityManager<Venue>();
porque essas classes terão alguns métodos especializados.Espero que você tenha entendido o que fiz até agora (e funciona)
Agora, meu problema é que toda entidade possui dois campos comuns:Id (int) e ativado (bool), devo usá -los ao excluir por id e quando a codificação Get and GetAll, porque devo obter apenas itens que foram ativados = true.Agora, eu sei que, como criei as classes Manager, eu poderia simplesmente usar c&p o código, mas queria saber se existe uma maneira de codificar isso na classe EntityManager e fazer com que todos os gerentes herdem o método, mas usando o concreto Aulas ?
algo assim:Na classe EntityManager:
public TEntity Get(int id) {
return _set.Where(T.ID==id);
}
Isso é basicamente o que eu quero:uma maneira de usar essas propriedades na classe base (EntityManager) onde elas são importantes (métodos deletebyid, get e getall) de forma que todas as classes Manager (ManagerVenue no exemplo) herdem esses métodos para que eu não precise escrevê-los todos e acabou?(tenho cerca de 100 entidades)
Solução
Você deve definir uma classe base ou interface para todas as suas entidades, algo como:
public class Entity {
public int Id { get; set; }
public bool Enabled { get; set; }
}
E no seu EntityManager
class adiciona uma restrição genérica ao TEntity como where TEntity : Entity
Então você poderá usar as propriedades comuns Id
e Enabled
dentro da sua classe base EntityManager
.