Tenho uma grade de interface do usuário do Kendo que atualmente estou permitindo a filtragem em várias colunas. Gostaria de saber se existe uma abordagem alternativa para remover a instrução switch externa?
Basicamente, quero criar um método de extensão para poder filtrar um IQueryable<T>
e quero descartar a instrução de caso externo para não precisar alterar os nomes das colunas.
private static IQueryable<Contact> FilterContactList(FilterDescriptor filter, IQueryable<Contact> contactList)
{
switch (filter.Member)
{
case "Name":
switch (filter.Operator)
{
case FilterOperator.StartsWith:
contactList = contactList.Where(w => w.Firstname.StartsWith(filter.Value.ToString()) || w.Lastname.StartsWith(filter.Value.ToString()) || (w.Firstname + " " + w.Lastname).StartsWith(filter.Value.ToString()));
break;
case FilterOperator.Contains:
contactList = contactList.Where(w => w.Firstname.Contains(filter.Value.ToString()) || w.Lastname.Contains(filter.Value.ToString()) || (w.Firstname + " " + w.Lastname).Contains( filter.Value.ToString()));
break;
case FilterOperator.IsEqualTo:
contactList = contactList.Where(w => w.Firstname == filter.Value.ToString() || w.Lastname == filter.Value.ToString() || (w.Firstname + " " + w.Lastname) == filter.Value.ToString());
break;
}
break;
case "Company":
switch (filter.Operator)
{
case FilterOperator.StartsWith:
contactList = contactList.Where(w => w.Company.StartsWith(filter.Value.ToString()));
break;
case FilterOperator.Contains:
contactList = contactList.Where(w => w.Company.Contains(filter.Value.ToString()));
break;
case FilterOperator.IsEqualTo:
contactList = contactList.Where(w => w.Company == filter.Value.ToString());
break;
}
break;
}
return contactList;
}
Algumas informações adicionais, estou usando o NHibernate Linq. Outro problema é que a coluna "Nome" na minha grade é na verdade "Nome" + "" + "Sobrenome" na minha entidade de contato. Também podemos assumir que todas as colunas filtráveis serão cadeias de caracteres.
EDIT Lembre-se de que isso precisa funcionar com o NHibernate Linq e o AST.
c#
design-patterns
Rippo
fonte
fonte
Respostas:
Respondendo a sua pergunta específica ,
No caso de "Nome", você o chama como;
Você deve adicionar uma sobrecarga como,
Assim, você pode chamar assim no campo "Empresa".
Isso evita a sobrecarga de forçar o chamador a criar uma matriz quando ele apenas pretende selecionar um campo / propriedade.
O que você provavelmente está procurando é o seguinte
Para remover completamente essa lógica ao definir
selector
epredicate
precisar de mais informações sobre como o filtro é construído. Se possível, o filtro deve ter as propriedadesselector
epredicate
como para o FilterContactList usar, que são construídas automaticamente.Expandindo um pouco isso,
O seu
FilterContactList
se tornariafonte
2[Domain.Model.Entities.Contact,System.Collections.Generic.IEnumerable
1 [System.String]]), contato). Qualquer valor (System.Func`2 [System.String, System .Boolean])) ': O objeto do tipo' System.Linq.Expressions.ConstantExpression 'não pode ser convertido no tipo' System.Linq.Expressions.LambdaExpression '. Se você tentou passar um delegado em vez de um LambdaExpression, isso não é suportado porque os delegados não são expressões analisáveis.Eu acho que uma maneira simples de fazer isso seria criar um mapa de nomes de propriedades para o Func:
por exemplo
E mude seu código para:
Você também pode eliminar completamente a opção criando uma pesquisa para a função correspondente:
Então, para juntar tudo:
NB - Não é redundante verificar c.FirstName se você também está verificando (c.FirstName + "" c.LastName)?
fonte
System.InvalidCastException Unable to cast object of type 'NHibernate.Hql.Ast.HqlParameter' to type 'NHibernate.Hql.Ast.HqlBooleanExpression'.