Eu tenho o nome do "classificar por propriedade" em uma seqüência de caracteres. Vou precisar usar o Lambda / Linq para classificar a lista de objetos.
Ex:
public class Employee
{
public string FirstName {set; get;}
public string LastName {set; get;}
public DateTime DOB {set; get;}
}
public void Sort(ref List<Employee> list, string sortBy, string sortDirection)
{
//Example data:
//sortBy = "FirstName"
//sortDirection = "ASC" or "DESC"
if (sortBy == "FirstName")
{
list = list.OrderBy(x => x.FirstName).toList();
}
}
- Em vez de usar um monte de ifs para verificar o nome do campo (sortBy), existe uma maneira mais limpa de fazer a classificação
- A classificação está ciente do tipo de dados?
c#
linq
lambda
linq-to-objects
DotnetDude
fonte
fonte
==
... o quê?Respostas:
Isso pode ser feito como
O framework .NET está lançando o lambda
(emp1,emp2)=>int
como umComparer<Employee>.
Isso tem a vantagem de ser fortemente digitado.
fonte
list.sort(functionDeclaredElsewhere)
Uma coisa que você pode fazer é mudar
Sort
para que ele use melhor as lambdas.Agora você pode especificar o campo a ser classificado ao chamar o
Sort
método.fonte
Você pode usar o Reflection para obter o valor da propriedade.
Onde TypeHelper tem um método estático como:
Você também pode consultar o LINQ dinâmico na biblioteca de exemplos do VS2008 . Você pode usar a extensão IEnumerable para converter a lista como um IQueryable e, em seguida, usar a extensão OrderBy de link dinâmico.
fonte
collection.ToList().OrderBy(x => TypeHelper.GetPropertyValue( x, sortBy)).ToList();
Foi assim que resolvi meu problema:
fonte
A construção da ordem por expressão pode ser lida aqui
Roubado descaradamente da página no link:
fonte
Você pode usar a reflexão para acessar a propriedade.
Notas
fonte
A classificação usa a interface IComparable, se o tipo a implementar. E você pode evitar os ifs implementando um IComparer personalizado:
e depois
fonte
Resposta 1:
Você poderá criar manualmente uma árvore de expressão que possa ser passada para OrderBy usando o nome como uma sequência. Ou você pode usar a reflexão como sugerido em outra resposta, o que pode ser menos trabalhoso.
Edit : Aqui está um exemplo de trabalho de construção de uma árvore de expressão manualmente. (Classificação em X.Value, quando apenas se conhece o nome "Valor" da propriedade). Você poderia (deveria) criar um método genérico para fazer isso.
Construir uma árvore de expressão requer que você conheça os tipos de particpação, no entanto. Isso pode ou não ser um problema no seu cenário de uso. Se você não souber em que tipo deve classificar, será mais fácil usar a reflexão.
Resposta para 2 .:
Sim, uma vez que o Comparador <T> .Default será usado para a comparação, se você não definir explicitamente o comparador.
fonte
Outro, desta vez para qualquer IQueryable:
Você pode passar vários critérios de classificação, assim:
fonte
Infelizmente, a solução fornecida pelo Rashack não funciona para tipos de valor (int, enumerações etc.).
Para que ele funcione com qualquer tipo de propriedade, esta é a solução que encontrei:
fonte
Adicionando o que @Samuel e @bluish fizeram. Isso é muito mais curto, pois o Enum era desnecessário neste caso. Além disso, como um bônus adicional quando Ascendente for o resultado desejado, você pode passar apenas 2 parâmetros em vez de 3, pois true é a resposta padrão para o terceiro parâmetro.
fonte
Se você obtém o nome da coluna de classificação e a direção da classificação como string e não deseja usar a sintaxe switch ou if \ else para determinar a coluna, este exemplo pode ser interessante para você:
Solução baseada no uso do Dictionary que conecta as colunas necessárias para classificar via Expressão> e sua sequência de teclas.
fonte