Pular para o conteúdo principal

Camada de Infra - Data

O projeto WMS.AI.Infra.Data é responsável pela persistência de dados do WMS.
Ele abstrai o acesso ao banco de dados e fornece repositórios modulares para diferentes contextos do sistema.

A implementação é baseada principalmente no Entity Framework Core, mas há suporte para consultas específicas via Dapper/SQL quando necessário.


Estrutura de Pastas

  • Extensions → Métodos de extensão usados para registrar os DbContexts e repositórios no container de DI.
  • Helpers → Utilitários auxiliares relacionados a persistência e banco de dados.
  • Persistence → Contém toda a lógica de persistência.
    • Contexts → múltiplos DbContext divididos por escopo (ex: pedidos, produtos, endereços).
    • Repositories → implementações modulares de repositórios para cada domínio.
    • RepositoryBase.cs → implementação base de repositório genérico em EF, permitindo reutilização.
  • Tenants → Estruturas relacionadas a multi-tenancy, permitindo isolar dados por cliente/instância.

Contexts

Cada DbContext representa um escopo específico do domínio e organiza as entidades relacionadas.
Exemplo:

  • PedidoContext → lida com tabelas de pedidos.
  • ProdutoContext → lida com tabelas de produtos.
  • EnderecoContext → lida com tabelas de endereçamento.
observação

Esse design modular reduz uso de memória, facilita manutenção, isolamento e escalabilidade.


Repositórios

Os repositórios seguem um modelo modular (ex: PedidosRepository, ProdutosRepository), implementam IRepositoryBase e herdam de um repositório base que encapsula operações comuns com Entity Framework.

Exemplo de Repositório com Entity Framework

IEnderecoRepository.cs
public interface IEnderecoRepository : IRepositoryBase<Endereco>{}
EnderecoRepository.cs
public class EnderecoRepository(EnderecoContext context)
: RepositoryBase<Endereco, EnderecoContext>(context), IEnderecoRepository
{
// Operações mais especificas e/ou atômicas podem ser adicionadas aqui.
}
informação

Ao herdar do RepositoryBase, temos acesso à todas as operações comuns de um repositório:

IRepositoryBase.cs
public interface IRepositoryBase<TEntity> where TEntity : class
{
IQueryable<TEntity> GetAll();

IQueryable<TEntity> GetById(object id);

Task<bool> ExistsAsync(object id, CancellationToken cancellationToken = default);

Task<bool> ExistsAsync(
Expression<Func<TEntity, bool>> predicate,
CancellationToken cancellationToken = default);

Task<List<TEntity>> GetAllAsync(CancellationToken cancellationToken = default);

Task<TEntity?> GetByIdAsync(object id, CancellationToken cancellationToken = default);

Task<List<TEntity>> FindAsync(Expression<Func<TEntity, bool>> predicate,
CancellationToken cancellationToken = default);

Task AddAsync(TEntity entity, CancellationToken cancellationToken = default);

Task AddRangeAsync(
IEnumerable<TEntity> entities,
CancellationToken cancellationToken = default);

Task UpdateAsync(TEntity entity, CancellationToken cancellationToken = default);

Task RemoveAsync(TEntity entity, CancellationToken cancellationToken = default);

Task RemoveByIdAsync(object id, CancellationToken cancellationToken = default);

Task<int> ExecuteUpdateAsync(
Expression<Func<TEntity, bool>> predicate,
Expression<Func<SetPropertyCalls<TEntity>, SetPropertyCalls<TEntity>>> setProperties,
CancellationToken cancellationToken = default
);

Task<int> ExecuteDeleteAsync(
Expression<Func<TEntity, bool>> predicate,
CancellationToken cancellationToken = default
);
}