Como especifico o argumento passado para orderby
usar um valor que considero como parâmetro?
Ex:
List<Student> existingStudends = new List<Student>{ new Student {...}, new Student {...}}
Implementação atual:
List<Student> orderbyAddress = existingStudends.OrderBy(c => c.Address).ToList();
Em vez de c.Address
, como posso tomar isso como parâmetro?
Exemplo
string param = "City";
List<Student> orderbyAddress = existingStudends.OrderByDescending(c => param).ToList();
OrderBy
é um recurso do Linq e estáIEnumerable
ativado, não um recurso específico paraList
. Sinta-se à vontade para reverter a edição ou alterá-la ainda mais :)Respostas:
Aqui está uma possibilidade usando reflexão ...
fonte
ThenBy
método .Você pode usar um pouco de reflexão para construir a árvore de expressão da seguinte maneira (este é um método de extensão):
orderByProperty
é o nome da propriedade pela qual você deseja ordenar e, se for verdadeiro como parâmetro paradesc
, a classificação será feita em ordem decrescente; caso contrário, classificará em ordem crescente.Agora você deve ser capaz de fazer
existingStudents.OrderBy("City",true);
ouexistingStudents.OrderBy("City",false);
fonte
Para expandir a resposta de @Icarus : se você quiser que o tipo de retorno do método de extensão seja um IOrderedQueryable em vez de um IQueryable, você pode simplesmente converter o resultado da seguinte maneira:
fonte
1) Instale System.Linq.Dynamic
2) Adicione o seguinte código
3) Escreva sua chave para selecionar a função Lambda
4) Use seus ajudantes
5) Você pode usá-lo com paginação ( PagedList )
Explicação
System.Linq.Dynamic nos permite definir o valor da string no método OrderBy. Mas dentro dessa extensão, a string será analisada em Lambda. Portanto, pensei que funcionaria se analisássemos Lambda em string e o entregássemos ao método OrderBy. E funciona!
fonte
fonte
Aqui está algo que inventei para lidar com uma descendente condicional. Você pode combinar isso com outros métodos de geração de
keySelector
função dinamicamente.Uso:
Observe que isso permite que você encadeie essa
.OrderBy
extensão com um novo parâmetro em qualquer IQueryable.fonte
Isso não deixa você passar por um
string
, como pediu em sua pergunta, mas ainda pode funcionar para você.O
OrderByDescending
método leva umFunc<TSource, TKey>
, então você pode reescrever sua função desta maneira:Existem outras sobrecargas para
OrderByDescending
também que levam aExpression<Func<TSource, TKey>>
, e / ou aIComparer<TKey>
. Você também pode olhar para eles e ver se eles fornecem algo útil.fonte
A única solução que funcionou para mim foi postada aqui https://gist.github.com/neoGeneva/1878868 por neoGeneva.
Vou postar novamente o código dele porque funciona bem e não gostaria que ele se perdesse nas interwebs!
fonte
Adicione o pacote nugget Dynamite ao seu código
Adicione o namespace Dynamite.Extensions Ex: using Dynamite.Extensions;
Dê Ordem por consulta como qualquer consulta SQL Ex .: students.OrderBy ("City DESC, Address"). ToList ();
fonte
Para estender a resposta de @Icarus: se você quiser classificar por dois campos, eu poderia executar a seguinte função (para um campo a resposta de Icarius funciona muito bem).
Esta é a função que o corpo retorna para a expressão lambda, ela trabalha com string e int, mas basta adicionar mais tipos para que funcione de acordo com a necessidade de cada programador
para usá-lo é feito o seguinte
se houver uma maneira melhor de fazer isso, seria ótimo se eles compartilhassem
Consegui resolver isso graças a: Como posso fazer uma expressão lambda de propriedades múltiplas com Linq
fonte
Estou muito atrasado para a festa, mas nenhuma dessas soluções funcionou para mim. Eu estava ansioso para experimentar o System.Linq.Dynamic, mas não consegui encontrar no Nuget, talvez depreciado? De qualquer jeito...
Aqui está uma solução que encontrei. Eu precisava usar dinamicamente uma mistura de OrderBy , OrderByDescending e OrderBy> ThenBy .
Simplesmente criei um método de extensão para o meu objeto de lista, um pouco hacky eu sei ... Eu não recomendaria isso se fosse algo que eu estivesse fazendo muito, mas é bom para um único.
fonte