Pular para o conteúdo
.NETFiltrando resultados
Módulo 05Consultas Avançadas

Filtrando resultados

intermediario 30 min de leitura·Atualizado · .NET 9
Resumo

Filtragem restringe os resultados por critérios exatos ou faixas (ex.: faixa de preço). Implementamos filtros compondo a IQueryable no repositório, mantendo tudo traduzido para SQL.

1. Objetivos de Aprendizagem#

  • Diferenciar filtragem de busca.
  • Adicionar critérios de filtro via query string.
  • Compor filtros na IQueryable sem materializar cedo.

2. Pré-requisitos#

  • Paginação (Módulo 30).

3. Conceito#

Filtragem restringe por condições precisas: "produtos com preço entre 100 e 200". Difere de busca (Módulo 32), que é textual e aproximada. O porquê de compor na IQueryable: o EF Core traduz para WHERE no SQL, filtrando no banco — eficiente e sem trazer tudo para a memória.

4. Mão na Massa#

4.1. Setup#

Estenda ProdutoParameters com os campos de filtro.

4.2. Implementação Passo a Passo#

  1. Parâmetros de filtro:
C#
public class ProdutoParameters : RequestParameters
{
    public decimal MinPreco { get; set; }
    public decimal MaxPreco { get; set; } = decimal.MaxValue;
    public bool ValidPrecoRange => MaxPreco > MinPreco;
}
  1. Composição no repositório:
C#
public async Task<PagedList<Produto>> GetAsync(
    Guid categoriaId, ProdutoParameters p, bool trackChanges, CancellationToken ct)
{
    var query = FindByCondition(x => x.CategoriaId == categoriaId, trackChanges)
        .Where(x => x.Preco >= p.MinPreco && x.Preco <= p.MaxPreco)
        .OrderBy(x => x.Nome);

    return await PagedList<Produto>.CreateAsync(query, p.PageNumber, p.PageSize, ct);
}
  1. Validação no serviço:
C#
if (!parameters.ValidPrecoRange)
    throw new MaxPriceRangeBadRequestException();

4.3. Executando#

Shell
curl "http://localhost:5000/api/categorias/{catId}/produtos?minPreco=100&maxPreco=200"

5. Exemplo Completo#

Filtros se acumulam na mesma IQueryable e só são executados na materialização (CreateAsyncToListAsync), garantindo uma única query eficiente.

6. Boas Práticas e Armadilhas#

FaçaEvite
Compor filtros na IQueryable (server-side)ToList() antes de filtrar (client-side)
Validar faixas (min ≤ max)Aceitar faixas incoerentes silenciosamente
Reaproveitar a query para paginaçãoConsultar duas vezes o banco desnecessariamente
Atenção

materializar com ToList() antes do Where traz toda a tabela para a memória e filtra na aplicação — desastre de performance. Filtre sempre no IQueryable.

7. Segurança e Produção#

  • Valide e limite os valores de filtro para evitar consultas patológicas.
  • Índices no banco nas colunas filtradas são essenciais para performance.

8. Exercícios#

  • Fácil: adicione um filtro por categoria ativa.
  • Médio: valide que minPreco >= 0.
  • Desafio: construa os filtros dinamicamente conforme os parâmetros presentes, sem if para cada um.

9. Resumo#

Filtragem compõe condições na IQueryable, traduzidas para WHERE no banco, com validação de faixas e execução única e eficiente.

10. Próximos Passos#

Módulo 32: busca textual, complementar à filtragem.

11. Referências#

31-01 — Filtrando resultados | Curso ASP.NET Core