Estou tentando classificar uma lista de produtos pelo preço.
O conjunto de resultados precisa listar produtos por preço, de baixo a alto, pela coluna LowestPrice
. No entanto, esta coluna é anulável.
Posso classificar a lista em ordem decrescente da seguinte forma:
var products = from p in _context.Products
where p.ProductTypeId == 1
orderby p.LowestPrice.HasValue descending
orderby p.LowestPrice descending
select p;
// returns: 102, 101, 100, null, null
No entanto, não consigo descobrir como classificar isso em ordem crescente.
// i'd like: 100, 101, 102, null, null
orderby p.LowestPrice ?? Int.MaxValue;
é uma maneira simples.OrderByDescending, ThenBy
é mais claro.orderby
, e do lado tem monitorado procurando por ele :)Respostas:
Tente colocar as duas colunas na mesma ordem, por.
Caso contrário, cada pedido será uma operação separada na coleção, reordenando-o a cada vez.
Isso deve ordenar os que têm um valor primeiro, "depois" a ordem do valor.
fonte
orderby p.LowestPrice == null, p.LowestPrice ascending
esperança ajuda alguém.Realmente ajuda a entender a sintaxe da consulta LINQ e como ela é convertida em chamadas de método LINQ.
Acontece que
será traduzido pelo compilador para
Isso não é enfaticamente o que você deseja. Isso classifica por
Product.LowestPrice.HasValue
emdescending
ordem e, em seguida, re-ordena toda a coleção porProduct.LowestPrice
emdescending
ordem.O que você quer é
que você pode obter usando a sintaxe da consulta,
Para detalhes das traduções da sintaxe da consulta para chamadas de método, consulte a especificação do idioma. Seriamente. Leia-o.
fonte
A solução para valores de string é realmente estranha:
O único motivo que funciona é porque a primeira expressão
OrderBy()
, classificabool
valores:true
/false
.false
O resultado segue primeiro otrue
resultado (nulos) eThenBy()
classifica os valores não nulos em ordem alfabética.Então, eu prefiro fazer algo mais legível como este:
Se
SomeString
for nulo, será substituído por"z"
e, em seguida, classificar tudo em ordem alfabética.NOTA: Esta não é uma solução definitiva, pois
"z"
vai primeiro do que os valores-zzebra
.ATUALIZAÇÃO 6/6/2016 - Sobre o comentário @jornhd, é realmente uma boa solução, mas ainda é um pouco complexa, portanto, recomendo envolvê-lo em uma classe Extension, como esta:
E use-o como:
fonte
Eu tenho outra opção nesta situação. Minha lista é objList, e eu tenho que pedir, mas os nulos devem estar no final. minha decisão:
fonte
Eu estava tentando encontrar uma solução LINQ para isso, mas não consegui resolver isso com as respostas aqui.
Minha resposta final foi:
fonte
minha decisão:
fonte
Isso é o que eu criei porque estou usando métodos de extensão e também meu item é uma string, portanto não
.HasValue
:Isso funciona com objetos LINQ 2 na memória. Não testei com a EF ou com qualquer DB ORM.
fonte
Abaixo está o método de extensão para verificar se é nulo se você deseja classificar na propriedade filho de um keySelector.
E use-o como:
fonte
Aqui está outra maneira:
SUP_APPROVED_IND is char(1) in Oracle db.
Observe que
r.SUP_APPROVED_IND.Trim() == null
é tratado comotrim(SUP_APPROVED_IND) is null
no Oracle db.Veja isto para detalhes: Como posso consultar valores nulos na estrutura da entidade?
fonte
Outra opção (útil para o nosso cenário):
Temos uma tabela de usuários, armazenando
ADName, LastName, FirstName
Alteramos o esquema da tabela e adicionamos uma coluna "SortIndex", que define alguns grupos de classificação. (Deixamos uma diferença de 5, para inserir grupos mais tarde)
Agora, em termos de consulta, seria:
em Expressões de método:
que produz o resultado esperado:
fonte