Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Programa só encontra os produtos pela categoria

Olá, eu evolui todas as partes da aplicação para aceitar o parâmetro de pesquisa, mas ele só acha os produtos se eu pesquisar pela categoria, e precisa ser o nome completo da categoria, como por exemplo, ele não acha nada se voce pesquisa a categoria "java", você precisa pesquisar "Livros de Programação / Java" para encontrar um resultado

Eu fiz o método GetProdutos receber o parâmetro: string pesquisa, ai ele filtra usando esse parâmetro, utilizando o Where()

var Pesquisa = TodosProdutos.Where(p => p.Nome == pesquisa || p.Categoria.Nome == pesquisa).ToList();

-Não sei por que ele não acha pelo nome do produto, somente pela categoria, sendo que no Where eu coloquei para filtrar pelo nome do produto ou pelo nome da categoria

E como posso fazer para ao invés de precisar pesquisar o nome completo da categoria (ex "Livros de Programação / Java"), pesquisar somente "Java" ou "Node"

Link do meu projeto: https://github.com/marcopandolfo/Projeto-Formacao-DotNet

2 respostas
solução!

Oi Marco Antonio, tudo bem?

Estou dando uma olhada no seu código aqui:

public IList<Produto> GetProdutos(string pesquisa)
{
    var TodosProdutos = dbSet.Include(p => p.Categoria).ToList();
    var Pesquisa = TodosProdutos.Where(p => p.Nome == pesquisa || p.Categoria.Nome == pesquisa).ToList();

    if (Pesquisa == null || Pesquisa.Count() == 0) //Se a pesquisa nao for encontrado, retorna todos os produtos
    {
        return null;
    }

    return Pesquisa;
}

Primeiro, vamos padronizar os nomes das variáveis, colocando com inicial em minúsculo: todosProdutos e mudando de Pesquisa para consulta, para identificar melhor a query do LINQ:

public IList<Produto> GetProdutos(string pesquisa)
{
    var todosProdutos = dbSet.Include(p => p.Categoria).ToList();
    var consulta = todosProdutos.Where(p => p.Nome == pesquisa || p.Categoria.Nome == pesquisa).ToList();

    if (consulta == null || consulta.Count() == 0) //Se a consulta nao for encontrado, retorna todos os produtos
    {
        return null;
    }

    return consulta;
}

Depois, vamos evitar chamar o método ToList() logo no começo do método. Em vez disso, podemos trabalhar com a variável todosProdutos como tipo IQueryable, e só no final retornar o resultado como List:

public IList<Produto> GetProdutos(string pesquisa)
{
    IQueryable<Produto> todosProdutos = dbSet.Include(p => p.Categoria);
    var consulta = todosProdutos.Where(p => p.Nome == pesquisa || p.Categoria.Nome == pesquisa);

    if (consulta == null || consulta.Count() == 0) //Se a pesquisa nao for encontrada, retorna todos os produtos
    {
        return null;
    }

    return consulta.ToList();
}

Se a consulta não tiver nenhum produto, não precisamos retornar nulo. Basta retornar a consulta vazia mesmo:

public IList<Produto> GetProdutos(string pesquisa)
{
    IQueryable<Produto> todosProdutos = dbSet.Include(p => p.Categoria);
    var consulta = todosProdutos.Where(p => p.Nome == pesquisa || p.Categoria.Nome == pesquisa);

    //if (consulta == null || consulta.Count() == 0) //Se a pesquisa nao for encontrada, retorna todos os produtos
    //{
    //    return null;
    //}

    return consulta.ToList();
}

Agora, não precisamos de duas variáveis de consulta. Podemos eliminar todosProdutos e trabalhar com a mesma variável consulta, como uma consulta inicial que traz todos os produtos, mas que depois é "refinada" pela cláusula Where:

public IList<Produto> GetProdutos(string pesquisa)
{
    IQueryable<Produto> consulta = dbSet.Include(p => p.Categoria);
    var consulta = consulta.Where(p => p.Nome == pesquisa || p.Categoria.Nome == pesquisa);

    return consulta.ToList();
}

Mas perceba que o parâmetro pesquisa pode conter um texto de busca, mas também pode ser:

  • nulo
  • string vazia
  • string com espaços em branco

Para esses casos, podemos colocar uma condição no método, para evitar fazer uma consulta complexa sem necessidade. Vamos usar o método IsNullOrWhiteSpace() de string:

public IList<Produto> GetProdutos(string pesquisa)
{
    IQueryable<Produto> consulta = dbSet.Include(p => p.Categoria);

    if (!string.IsNullOrWhiteSpace(pesquisa))
    {
        var consulta = consulta.Where(p => p.Nome == pesquisa || p.Categoria.Nome == pesquisa);
    }

    return consulta.ToList();
}

Agora note que você está usando a cláusula Where com um filtro que exige "correspondência absoluta", isto é, o valor buscado deve "bater" exatamente com o nome que está no banco de dados. Porém, a ideia é poder buscar por parte do nome, por exemplo: uma pesquisa "JavaS" deveria trazer todos os livros e categorias contendo "JavaScript".

Por isso, vamos usar o método Contains() da string, para poder buscar por parte do nome:

public IList<Produto> GetProdutos(string pesquisa)
{
    IQueryable<Produto> consulta = 
        dbSet.Include(p => p.Categoria);

    if (!string.IsNullOrWhiteSpace(pesquisa))
    {
        var consulta = consulta
            .Where(p => p.Nome.Contains(pesquisa) 
                || p.Categoria.Nome.Contains(pesquisa));
    }

    return consulta.ToList();
}

Estou fazendo essas sugestões aqui no fórum, mas na verdade não testei o código. Por favor faça esse teste e veja se funciona.

Era isso mesmo, obrigado