Closed marcelohnq closed 7 months ago
A primeira mudança feita, para essa tarefa, foi criar uma classe genérica para realizar consultas no banco de dados, a Repository/GenericDbContext
, e uma classe base para todos os data model
, a Models/Entity.cs
. Com essas classes foi possível aproveitar o mesmo código para se conectar com diferentes tabelas do banco de dados.
Foi construído uma consulta no BD que realiza a paginação, de forma genérica para qualquer entidade:
public async Task<EntityList<TEntity>> GetPagination(int page, int size = 10)
{
int total = _dbSet.AsQueryable().Count();
int current = (page - 1) * size;
int last = page * size;
List<TEntity> list = await _dbSet
.OrderBy(e => e.Id)
.Where(e => e.Id > current)
.Take(size)
.ToListAsync();
return new(list) { HasNext = last < total, TotalCount = total };
}
Aqui existe uma grande preocupação na performance, principalmente quando existir milhões da dados no BD. Para melhorar a performance foi utilizado o Where(e => e.Id > current)
em cima da Primary Key
das tabelas (essa consulta é executada direto no BD).
Outras possíveis melhorias de performance seria:
Com a criação da classe genérica, a classe ProductService
foi removida. No controlador foi adicionado a injeção de dependência:
// Program.cs
builder.Services.AddScoped(typeof(IGenericDbContext<>), typeof(GenericDbContext<>));
E alterado no controlador:
// Parte2Controller
private readonly IGenericDbContext<Product> _ctxProducts;
private readonly IGenericDbContext<Customer> _ctxCustomer;
As classes Models/CustomerList
e Models/ProductList
foram trocadas pela classe Models/EntityList.cs
.
A criação do GenericDbContext
resolveu a repetição de código nas classes CustomerService
e ProductService
, que apenas realizava consultas no BD.
Essa API deveria retornar os produtos cadastrados de forma paginada. O usuário informa a página (page) desejada e o sistema retorna os 10 itens da mesma. O problema é que não importa qual número de página é utilizado: os resultados estão vindo sempre os mesmos. E não apenas os 10.
Você precisa portanto: