none
Aplicar filtro em pesquisa no banco C# RRS feed

  • Pergunta

  • meu data grid é povoado com todos os clientes, como abaixo.

       DgvClientes.DataSource = clientebll.PovoaGrid();

    tem como eu usar algum filtro com LINQ para fazer um select dentro do datagrid povoado?

    fazer o select direto no banco e ir retornando eu consigo, como abaixo.

     string s = txtConsultaNome.Text;

                    if (txtConsultaNome.TextLength >= 3)
                    {
                        ClienteBLL clientebll = new ClienteBLL();
                        gridCliente.DataSource = clientebll.BuscaPorNome(s);

    mas eu queria algo como:

    tipo: com o grid ja povoado, ao que o usuario escrever no Textbox dispara um filtro com os dados que o grid ja tem, tem como fazer isso usando linq, ou outro metodo?

    domingo, 22 de maio de 2016 13:50

Respostas

  • Em primeiro lugar, parabéns por estar na contra mão de uma quantidade expressiva de programadores, por estar usando orientação à objeto. Você está retornando um List<T>, que é uma lista de objetos. Você pode aplicar uma expressão lambda(conforme já sugerido) para fazer o que você quer, mais ou menos assim:

    gridCliente.DataSource = clientebll.BuscaPorNome(s).Where(p => p.Nome.Contains(Texbox1.Text)).ToList();

    List<T> possem uma gama de métodos de extensão que se equiparam à SQL. Entre os mais usados estão:

    OrderBy e OrderByDescending: Ordena a lista pelo campo desejado: SuaLista = SuaLista.OrderBy(p => p.CAMPO).ToList();

    FirstOrDefault: Retorna um objeto da lista correspondente ao critério usado: SuaLista.FirstOrDefault(p => p.CAMPO == "Valor");

    Where: Cria uma lista com objetos correspondente ao critério: SuaLista.Where(p => p.CAMPO == "Valor").ToList();

    Existem vários outros e eles podem ser usados em combinação:

    OutraLista = SuaLista.Where(p => p.CAMPO == "Valor & p.CAMPO2 == "Outro valor").OrderBy(p => p.CODIGO).ToList();
    //Busca os valores "Campo=valor, campo="outro valor" e ordena a lista pelo campo CODIGO

    Vale destacar que o "p" que usei em todas os exemplos, é apenas uma variável qualquer. Ele se refere aos ítens da lista, representando uma abstração do tipo de elemento da lista. Você pode inclusive criar seus próprios métodos de extensão para listas. Este exemplo, que postei em outro site, mostra várias coisas que se pode fazer com um DataGridView, uma lista de dados e um pouquinho de criatividade. Qualquer dúvida, estamos aqui para ajudar

    • Marcado como Resposta Thales F Quintas segunda-feira, 23 de maio de 2016 19:02
    domingo, 22 de maio de 2016 15:41
  • Boa tarde,

    Para facilitar, execute o código abaixo e verifique o que retorna:

    private void txtNomeCli_TextChanged(object sender, EventArgs e)
    {
        List<ClienteModel> clientes = new List<ClienteModel>();
        try
        {
            string s = txtNomeCli.Text;
            clientes = new ClienteBLL().PovoaGrid();
            MessageBox.Show("Quantidade antes de aplicar o Filtro" + clientes.Count);
    
            if (s.Length > 2)
            {
                clientes = clientes.Where(x => x.NomeCliente.Contains(s)).ToList();
                MessageBox.Show("Quantidade após aplicar o Filtro" + clientes.Count);
                if (clientes.Count == 0)
                {
                    MessageBox.Show("Cliente não consta no cadastro");
                }
                //  DgvClientes.AutoGenerateColumns = false;
                DgvClientes.CurrentCell.Value.ToString().ToUpper();
            }
    
            DgvClientes.DataSource = clientes.ToList();
    
        }
        catch (Exception erro)
        {
            MessageBox.Show("Verifique" + erro); return; throw erro;
        }
    }


    Se a resposta contribuiu com seu aprendizado por favor marque como util, se solucionou seu problema marque como resposta.

    • Marcado como Resposta TiagoJesusTJS terça-feira, 24 de maio de 2016 09:36
    domingo, 22 de maio de 2016 17:13

Todas as Respostas

  • Bom dia,

    Tiago, é possível sim. Se poder postar o código da sua consulta (método BuscarPorNome) vai facilitar o entendimento e consequentemente  a ajuda desejada.
    Seria algo parecido com:
    lista.Where(x => x.Nome.Contains(s)).ToList();

    Se precisar de ajuda, poste o código por favor.

    Espero ter ajudado.

    Att,


    Se a resposta contribuiu com seu aprendizado por favor marque como util, se solucionou seu problema marque como resposta.

    domingo, 22 de maio de 2016 14:40
  • Blza Silvaney, segue abaixo:

    na VIEW

    try
                {
                    string s = txtNomeCli.Text;

                    if (s.Length > 2)
                    {
                        ClienteBLL clientebll = new ClienteBLL();
                       DgvClientes.DataSource = clientebll.PovoaGrid();

    na BLL
     public List<ClienteModel> PovoaGrid()
            {
                return new ClienteDAL().ListaClientes();
            }

    na DAL

     public List<ClienteModel> ListaClientes()
            {
                var ListaClientes = new List<ClienteModel >();

                try
                {
                    using (var sqlcom = sqlconn.CreateCommand ())
                    {
                    sqlcom.CommandText = "SELECT * FROM CLIENTE";
                    sqlconn.Open();
                    SqlDataReader dataReader = sqlcom.ExecuteReader();
                    if (dataReader.HasRows)
                    {
                        while (dataReader.Read())
                        {
                             var cli = new ClienteModel();

                            cli.Bairro = Convert.ToString(dataReader ["bairro"]);
                            cli.Cep = Convert.ToString(dataReader["cep"]);
                            cli.Cidade  = Convert.ToString(dataReader ["cidade"]);
                            cli.Cnpj  = Convert.ToString(dataReader ["cnpj"]);
                            cli.Complemento  = Convert.ToString(dataReader ["complemento"]);
                            cli.Endereco  = Convert.ToString(dataReader ["endereco"]);
                            cli.Idcliente  = Convert.ToInt32(dataReader ["idcliente"]);
                            cli.NomeCliente  = Convert.ToString(dataReader ["nomeCliente"]);
                            cli.Sigla  = Convert.ToString(dataReader ["sigla"]);
                            cli.Uf = Convert.ToString(dataReader ["uf"]);

                            ListaClientes.Add(cli);
                        }
                    }
                    return ListaClientes;
                    }
                }
                catch (Exception ex)
                { throw ex; }
            }
    domingo, 22 de maio de 2016 15:25
  • Em primeiro lugar, parabéns por estar na contra mão de uma quantidade expressiva de programadores, por estar usando orientação à objeto. Você está retornando um List<T>, que é uma lista de objetos. Você pode aplicar uma expressão lambda(conforme já sugerido) para fazer o que você quer, mais ou menos assim:

    gridCliente.DataSource = clientebll.BuscaPorNome(s).Where(p => p.Nome.Contains(Texbox1.Text)).ToList();

    List<T> possem uma gama de métodos de extensão que se equiparam à SQL. Entre os mais usados estão:

    OrderBy e OrderByDescending: Ordena a lista pelo campo desejado: SuaLista = SuaLista.OrderBy(p => p.CAMPO).ToList();

    FirstOrDefault: Retorna um objeto da lista correspondente ao critério usado: SuaLista.FirstOrDefault(p => p.CAMPO == "Valor");

    Where: Cria uma lista com objetos correspondente ao critério: SuaLista.Where(p => p.CAMPO == "Valor").ToList();

    Existem vários outros e eles podem ser usados em combinação:

    OutraLista = SuaLista.Where(p => p.CAMPO == "Valor & p.CAMPO2 == "Outro valor").OrderBy(p => p.CODIGO).ToList();
    //Busca os valores "Campo=valor, campo="outro valor" e ordena a lista pelo campo CODIGO

    Vale destacar que o "p" que usei em todas os exemplos, é apenas uma variável qualquer. Ele se refere aos ítens da lista, representando uma abstração do tipo de elemento da lista. Você pode inclusive criar seus próprios métodos de extensão para listas. Este exemplo, que postei em outro site, mostra várias coisas que se pode fazer com um DataGridView, uma lista de dados e um pouquinho de criatividade. Qualquer dúvida, estamos aqui para ajudar

    • Marcado como Resposta Thales F Quintas segunda-feira, 23 de maio de 2016 19:02
    domingo, 22 de maio de 2016 15:41
  • Kerplunk fiquei confuso nesse trecho:

    gridCliente.DataSource = clientebll.BuscaPorNome(s).Where(p => p.Nome.Contains(Texbox1.Text)).ToList();

    gridCliente.DataSource = clientebll.BuscaPorNome(s) //aqui ja estou disparando um filtro la na query usando parametros, certo?
    //sendo assim o restante abaixo nao fica desnecessario?

    .Where(p => p.Nome.Contains(Texbox1.Text)).ToList();

    ///porem, se eu faço assim como abaixo nao mostra nada no meu grid;

    gridCliente.DataSource = clientebll.BuscaPorNome().Where(p => p.Nome.Contains(s)).ToList();

    //o que estou fazendo de errado maninho?


    domingo, 22 de maio de 2016 16:09
  • Bom dia,

    Tiago, você pode alterar apenas na View. Pode fazer assim:

    DgvClientes.DataSource = clientebll.PovoaGrid().Where(x => x.NomeCliente.Contains(s)).ToList();

    Lembrando que vai precisar a adicionar a referência: "using System.Linq".

    Att,


    Se a resposta contribuiu com seu aprendizado por favor marque como util, se solucionou seu problema marque como resposta.

    • Sugerido como Resposta Silvaney domingo, 22 de maio de 2016 16:11
    domingo, 22 de maio de 2016 16:11
  • //Desculpa to começando agora....la na DAL a lista volta cheia, mas chega vazia aqui na View.
    vim passando com Breakpoint, ela chega na View Count=0
    
      private void txtNomeCli_TextChanged(object sender, EventArgs e)
            {
                List<ClienteModel> clientes = new List<ClienteModel>();
                try
                {
                    string s = txtNomeCli.Text;
    
                    if (s.Length > 2)
                    {
                      clientes = new ClienteBLL().PovoaGrid().Where(x => x.NomeCliente.Contains(s)).ToList();
                        if(clientes != null )
                        {
                            DgvClientes.DataSource = clientes.ToList();
                        }
                        else
                        {
                            MessageBox.Show("Cliente não consta no cadastro");
                        }
                      //  DgvClientes.AutoGenerateColumns = false;
                       DgvClientes.CurrentCell.Value.ToString().ToUpper();
                    }
    
                }
                catch (Exception erro)
                {
                    MessageBox.Show("Verifique"+erro ); return; throw erro;
                }
            }
    

    domingo, 22 de maio de 2016 16:34
  • Boa tarde,

    Para facilitar, execute o código abaixo e verifique o que retorna:

    private void txtNomeCli_TextChanged(object sender, EventArgs e)
    {
        List<ClienteModel> clientes = new List<ClienteModel>();
        try
        {
            string s = txtNomeCli.Text;
            clientes = new ClienteBLL().PovoaGrid();
            MessageBox.Show("Quantidade antes de aplicar o Filtro" + clientes.Count);
    
            if (s.Length > 2)
            {
                clientes = clientes.Where(x => x.NomeCliente.Contains(s)).ToList();
                MessageBox.Show("Quantidade após aplicar o Filtro" + clientes.Count);
                if (clientes.Count == 0)
                {
                    MessageBox.Show("Cliente não consta no cadastro");
                }
                //  DgvClientes.AutoGenerateColumns = false;
                DgvClientes.CurrentCell.Value.ToString().ToUpper();
            }
    
            DgvClientes.DataSource = clientes.ToList();
    
        }
        catch (Exception erro)
        {
            MessageBox.Show("Verifique" + erro); return; throw erro;
        }
    }


    Se a resposta contribuiu com seu aprendizado por favor marque como util, se solucionou seu problema marque como resposta.

    • Marcado como Resposta TiagoJesusTJS terça-feira, 24 de maio de 2016 09:36
    domingo, 22 de maio de 2016 17:13
  • Você está preenchendo um List<T> à partir do banco de dados. Você pode filtrar novamente esse conteúdo usando uma expressão lambda. Obviamente você poderia especificar na sua query o equivalente da expressão lambda e trazer do banco de dados exatamente o que você quer. Estou apenas mostrando que você pode filtrar e refiltrar uma série de dados sem ter acessado o banco de dados.

    Estou supondo que "BuscaPorNome" traria uma lista de dados do banco de acordo com um nome. Se a lista de dados estiver vazia, "Where" também não trará nada e por isso nada aparece no grid, com exceção dos nomes de colunas. No link que passei anteriormente, tem um exemplo bem bacana sobre isso. Dê uma olhadinha nele.

    Usando Entity Framework, você poderia usar as expressões lambda como queries se quiser, mas isso é assunto para todo um tópico.

    segunda-feira, 23 de maio de 2016 08:33
  • Kerplunk

    agradeço, mas ainda nao sei usar lambda ou EF

    terça-feira, 24 de maio de 2016 02:44

  • consegui resolver com base no raciocinio que voce colocou Silvaney, mas obrigado ao Kerplunk tambem.

     var s = txtNomeCli.Text;
                try
                {
                    if (s.Length > 3)
                    {
                    clientes = new ClienteBLL().PovoaGrid();
                    clientes.Where(x => x.NomeCliente.Contains(s));
                    DgvClientes.DataSource = clientes.ToList();
                    }
                }
                catch (Exception erro)
                {
                    MessageBox.Show("Verifique o nome digitado!" + erro); return; throw erro;
                }


    terça-feira, 24 de maio de 2016 09:37