Filtros dinâmicos em listagem de registros
07/06/2012
0
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
Posts
07/06/2012
Joel Rodrigues
08/06/2012
Felipe Bulle
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!
08/06/2012
Rachel Andrade
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.
08/06/2012
Joel Rodrigues
Eu também ia sugerir isso, mas adicionaria uma dica: use expressões Lambda, pode ser que enxugue mais o seu código.
08/06/2012
Felipe Bulle
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!!!
08/06/2012
Joel Rodrigues
Ao invés de db.Atividades, você passa a fazer os filtros sobre a variável consulta.
Boa sorte.
08/06/2012
Joel Rodrigues
Ao invés de db.Atividades, você passa a fazer os filtros sobre a variável consulta.
Boa sorte.
08/06/2012
Joel Rodrigues
//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.
08/06/2012
Felipe Bulle
Aprendi muito!
Resolvido!
Abraço!
08/06/2012
Joel Rodrigues
Boa sorte em seus projetos.
Clique aqui para fazer login e interagir na Comunidade :)