Array
(
)

Filtros dinâmicos em listagem de registros

Felipe Bulle
   - 07 jun 2012

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:
#Código


        [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:
#Código
        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!!!

Joel Rodrigues
   - 07 jun 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.

0
|
0

Felipe Bulle
   - 08 jun 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:

#Código

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!

0
|
0

Rachel Andrade
   - 08 jun 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:
#Código

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.

0
|
0

Joel Rodrigues
   - 08 jun 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.

0
|
0

Felipe Bulle
   - 08 jun 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:

#Código

consulta = from atividade in db.Atividades
where atividade.AtividadeStatusID == idStatus
orderby atividade.dataCriacao
select atividade;


e depois você faz de novo:

#Código
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!!!

0
|
0

Joel Rodrigues
   - 08 jun 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.

0
|
0

Joel Rodrigues
   - 08 jun 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.

0
|
0

Joel Rodrigues
   - 08 jun 2012

Saca só como ficaria com Lambda Expressions:
#Código

//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.

0
|
0

Felipe Bulle
   - 08 jun 2012

Pessoal, muito obrigado a todos pela força!

Aprendi muito!

Resolvido!

Abraço!

0
|
0

Joel Rodrigues
   - 08 jun 2012

Que bom que deu certo, cara, ficamos felizes em ter ajudado.
Boa sorte em seus projetos.

0
|
0