Filtros dinâmicos em listagem de registros
Boa noite, pessoal!
Estou fazendo uma página (C#, MVC) que lista registros de uma tabela. Eu adicionei textBoxs e DropDownLists para o usuário fazer filtros sobre as colunas que estão em exibição na página.
O usuário, entretanto, pode querer utilizar o filtro apenas em uma ou algumas colunas. Eu não consegui pensar num jeito de programar isso de forma elegante... olha o que eu fiz:
No meu Controller:
Na minha classe .c está assim:
A questão é... se o usuário informar só um resumo procurado e nenhum status??? Ou se informar só um status e nenhum resumo procurado???
Eu pensei em usar vários IF´s para resolver isso, mas ía ficar horrível, ainda mais se eu quisesse aumentar as possibilidades de filtragem...
Deve existir alguma solução ou algum design que resolva este meu problema, só não consegui encontrar...
Alguém tem alguma idéia???
Valeu!!!
Estou fazendo uma página (C#, MVC) que lista registros de uma tabela. Eu adicionei textBoxs e DropDownLists para o usuário fazer filtros sobre as colunas que estão em exibição na página.
O usuário, entretanto, pode querer utilizar o filtro apenas em uma ou algumas colunas. Eu não consegui pensar num jeito de programar isso de forma elegante... olha o que eu fiz:
No meu Controller:
[AcceptVerbs(HttpVerbs.Post)] public ActionResult Index(FormCollection collection) { //Pega o valor a ser procurado no campo resumo da tabela string searchResumo = collection[searchResumo]; //Pega o id do Status selecionado pelo usuário no Drop Down List string searchStatus = collection[AtividadeStatusID]; //Chama o método para pegar os registros com os critérios selecionados pelo usuário - AQUI COMEÇA O PROBLEMA var atividades = atividadeRepository.FindAtividades(searchResumo, searchStatus); return View(AtividadeListView, atividades); } }
Na minha classe .c está assim:
public IQueryable<Atividade> FindAllAtividadesResumo(string resumoProcurado, string idStatus) { return from atividade in db.Atividades where atividade.resumo.Contains (resumoProcurado) && atividade.AtividadeStatusID == idStatus orderby atividade.dataCriacao select atividade; }
A questão é... se o usuário informar só um resumo procurado e nenhum status??? Ou se informar só um status e nenhum resumo procurado???
Eu pensei em usar vários IF´s para resolver isso, mas ía ficar horrível, ainda mais se eu quisesse aumentar as possibilidades de filtragem...
Deve existir alguma solução ou algum design que resolva este meu problema, só não consegui encontrar...
Alguém tem alguma idéia???
Valeu!!!
Felipe Bulle
Curtidas 0
Respostas
Joel Rodrigues
07/06/2012
Não vejo outra forma rápida a não ser verificar se os parâmetros são nulos e filtrar apenas pelos parâmetros não nulos.
GOSTEI 0
Felipe Bulle
07/06/2012
Obrigado pelo retorno!
Até aí sem problemas... o problema é que não sei se estou fazendo isso da melhor forma. Seria algo parecido com isso:
Ou teria uma forma melhor? Porque se eu aumentar o número de critérios, estou ferrado... rs...
Mais uma vez, obrigado!
Até aí sem problemas... o problema é que não sei se estou fazendo isso da melhor forma. Seria algo parecido com isso:
public IQueryable<Atividade> FindAllAtividadesResumo(string resumoProcurado, string idStatus) { if (string.isNullOrEmpty(resumoProcurado) && string.isNullOrEmpty(resumoProcurado)){ return from atividade in db.Atividades orderby atividade.dataCriacao select atividade; }elseif (string.isNullOrEmpty(resumoProcurado)){ return from atividade in db.Atividades where atividade.AtividadeStatusID == idStatus orderby atividade.dataCriacao select atividade; }elseif (string.isNullOrEmpty(idStatus)){ return from atividade in db.Atividades where atividade.resumo.Contains (resumoProcurado) orderby atividade.dataCriacao select atividade; }else{ return from atividade in db.Atividades where atividade.resumo.Contains (resumoProcurado) && atividade.AtividadeStatusID == idStatus orderby atividade.dataCriacao select atividade; } }
Ou teria uma forma melhor? Porque se eu aumentar o número de critérios, estou ferrado... rs...
Mais uma vez, obrigado!
GOSTEI 0
Rachel Andrade
07/06/2012
Assim, não pude testar aqui... mas me veio uma ideia à cabeça e vou compartilhar com você. Analise o seguinte código e veja o que acha dele:
Ou seja, vc inicia com a lista completa e vai filtrando de acordo com os parâmetros não nulos sequencialmente, o que terminar por ter o mesmo efeito que um AND.
IQueryable<Atividade> consulta = null; //Todos os dados, sem filtro consulta = from atividade in db.Atividades orderby atividade.dataCriacao select atividade; if (string.isNullOrEmpty(resumoProcurado)){ consulta = from atividade in db.Atividades where atividade.AtividadeStatusID == idStatus orderby atividade.dataCriacao select atividade; if (string.isNullOrEmpty(idStatus)){ consulta = from atividade in db.Atividades where atividade.resumo.Contains (resumoProcurado) orderby atividade.dataCriacao select atividade; //...demais filtros return consulta;
Ou seja, vc inicia com a lista completa e vai filtrando de acordo com os parâmetros não nulos sequencialmente, o que terminar por ter o mesmo efeito que um AND.
GOSTEI 0
Joel Rodrigues
07/06/2012
Poxa, Rachel, lendo meus pensamentos? rsrs
Eu também ia sugerir isso, mas adicionaria uma dica: use expressões Lambda, pode ser que enxugue mais o seu código.
Eu também ia sugerir isso, mas adicionaria uma dica: use expressões Lambda, pode ser que enxugue mais o seu código.
GOSTEI 0
Felipe Bulle
07/06/2012
Oi Rachel!
Valeu pela dica...
Só uma dúvida para confirmar...
Eu vi que primeiro você coloca todos os dados sem filtro...
Aí você vai recarregando a variável consulta conforme os valores que tiverem que ser filtrados... Mas quando você coloca na variável consulta, por exemplo:
e depois você faz de novo:
isso não vai anular o efeito da primeira atribuição? Ou vai ter efeito de uma concatenação de AND´s???
Mais uma vez obrigado!!!
Valeu pela dica...
Só uma dúvida para confirmar...
Eu vi que primeiro você coloca todos os dados sem filtro...
Aí você vai recarregando a variável consulta conforme os valores que tiverem que ser filtrados... Mas quando você coloca na variável consulta, por exemplo:
consulta = from atividade in db.Atividades where atividade.AtividadeStatusID == idStatus orderby atividade.dataCriacao select atividade;
e depois você faz de novo:
consulta = from atividade in db.Atividades where atividade.resumo.Contains (resumoProcurado) orderby atividade.dataCriacao select atividade;
isso não vai anular o efeito da primeira atribuição? Ou vai ter efeito de uma concatenação de AND´s???
Mais uma vez obrigado!!!
GOSTEI 0
Joel Rodrigues
07/06/2012
Acho que a colega se confundiu um pouco. =)
Ao invés de db.Atividades, você passa a fazer os filtros sobre a variável consulta.
Boa sorte.
Ao invés de db.Atividades, você passa a fazer os filtros sobre a variável consulta.
Boa sorte.
GOSTEI 0
Joel Rodrigues
07/06/2012
Acho que a colega se confundiu um pouco. =)
Ao invés de db.Atividades, você passa a fazer os filtros sobre a variável consulta.
Boa sorte.
Ao invés de db.Atividades, você passa a fazer os filtros sobre a variável consulta.
Boa sorte.
GOSTEI 0
Joel Rodrigues
07/06/2012
Saca só como ficaria com Lambda Expressions:
Boa sorte.
//Todos os dados, sem filtro var consulta = db.Atividades; if (!String.IsNullOrEmpty(idStatus)) consulta = consulta.Where(a => a.AtividadeStatusID == idStatus); if (!String.IsNullOrEmpty(resumoProcurado){ consulta = consulta.Where(a => a.Resumo.Contains(resumoProcurado)); //...demais filtros return consulta;
Boa sorte.
GOSTEI 0
Felipe Bulle
07/06/2012
Pessoal, muito obrigado a todos pela força!
Aprendi muito!
Resolvido!
Abraço!
Aprendi muito!
Resolvido!
Abraço!
GOSTEI 0
Joel Rodrigues
07/06/2012
Que bom que deu certo, cara, ficamos felizes em ter ajudado.
Boa sorte em seus projetos.
Boa sorte em seus projetos.
GOSTEI 0