Implementando busca textual
ResumoBusca (searching) encontra registros por correspondência textual parcial (ex.: nome contém "mou"). Implementamos com
Contains, compondo aIQueryablejunto de filtragem e paginação.
1. Objetivos de Aprendizagem#
- Distinguir busca de filtragem.
- Implementar busca por termo parcial no repositório.
- Compor busca com filtros e paginação existentes.
2. Pré-requisitos#
- Filtragem (Módulo 31).
3. Conceito#
Busca é textual e aproximada: "traga produtos cujo nome contenha o termo". Filtragem é por critérios exatos/faixas. O porquê de separá-las: têm semânticas diferentes e o cliente as combina (buscar "mouse" e filtrar por preço).
Contains no LINQ é traduzido para LIKE '%termo%' no SQL.
4. Mão na Massa#
4.1. Setup#
Adicione SearchTerm aos parâmetros.
4.2. Implementação Passo a Passo#
- Parâmetro:
public class ProdutoParameters : RequestParameters
{
public string? SearchTerm { get; set; }
// ... filtros e paginação
}
- Composição no repositório:
var query = FindByCondition(x => x.CategoriaId == categoriaId, trackChanges)
.Where(x => x.Preco >= p.MinPreco && x.Preco <= p.MaxPreco);
if (!string.IsNullOrWhiteSpace(p.SearchTerm))
{
var termo = p.SearchTerm.Trim().ToLower();
query = query.Where(x => x.Nome.ToLower().Contains(termo));
}
query = query.OrderBy(x => x.Nome);
4.3. Executando#
curl "http://localhost:5000/api/categorias/{catId}/produtos?searchTerm=mou&maxPreco=500"
5. Exemplo Completo#
Busca, filtro e paginação convivem na mesma IQueryable, resultando em uma consulta SQL com WHERE ... LIKE ... AND ... e OFFSET/FETCH.
6. Boas Práticas e Armadilhas#
| Faça | Evite |
|---|---|
| Tratar termo vazio/nulo como "sem busca" | Aplicar Contains("") e degradar a query |
| Normalizar caixa (lower) de forma consistente | Comparações sensíveis a caixa não intencionais |
Compor na IQueryable | Buscar em memória após ToList() |
Atenção
ToLower()pode impedir o uso de índices e forçar table scan. Em SQL Server, uma collation case-insensitive já resolve a comparação semToLower; avalie a estratégia conforme o provedor.
7. Segurança e Produção#
- Como usamos LINQ/EF Core parametrizado, não há risco de SQL injection — nunca concatene o termo em SQL cru.
- Para busca textual avançada, considere Full-Text Search do banco ou um motor dedicado.
8. Exercícios#
- Fácil: permita busca também pela descrição.
- Médio: ignore acentos na comparação (dica: normalização/collation).
- Desafio: substitua
Containspor Full-Text Search e compare desempenho.
9. Resumo#
Busca textual usa Contains (→ LIKE) composto na IQueryable, convivendo com filtro e paginação numa única query. Atenção a caixa/collation e índices.
10. Próximos Passos#
Módulo 33: ordenação dinâmica por campos escolhidos pelo cliente.
11. Referências#
- Microsoft Learn — Consultas LINQ no EF Core
- Microsoft Learn — Funções de string traduzidas
- Microsoft Learn — Full-Text Search