가격별로 제품 목록을 정렬하려고합니다.
결과 집합은 열별로 가격을 기준으로 제품을 나열해야합니다 LowestPrice
. 그러나이 열은 널 입력 가능합니다.
목록을 내림차순으로 정렬 할 수 있습니다.
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
그러나 이것을 오름차순으로 정렬하는 방법을 알 수 없습니다.
// i'd like: 100, 101, 102, null, null
답변
두 열을 모두 같은 순서로 배치하십시오.
orderby p.LowestPrice.HasValue descending, p.LowestPrice
그렇지 않으면 각 orderby는 매번 컬렉션을 다시 정렬하는 별도의 작업입니다.
먼저 값을 가진 것들을 순서대로 정렬해야합니다.
답변
LINQ 쿼리 구문과 LINQ 메서드 호출로 변환되는 방법을 이해하는 데 실제로 도움이됩니다.
그것은 밝혀졌다
var products = from p in _context.Products
where p.ProductTypeId == 1
orderby p.LowestPrice.HasValue descending
orderby p.LowestPrice descending
select p;
컴파일러에 의해
var products = _context.Products
.Where(p => p.ProductTypeId == 1)
.OrderByDescending(p => p.LowestPrice.HasValue)
.OrderByDescending(p => p.LowestPrice)
.Select(p => p);
이것은 당신이 원하는 것이 아닙니다. 이 종류에 의해 Product.LowestPrice.HasValue
에서 descending
위해 다음과 같은 방법으로 전체 컬렉션을-가 정렬 다시 Product.LowestPrice
의 descending
순서.
당신이 원하는 것은
var products = _context.Products
.Where(p => p.ProductTypeId == 1)
.OrderByDescending(p => p.LowestPrice.HasValue)
.ThenBy(p => p.LowestPrice)
.Select(p => p);
쿼리 구문을 사용하여 얻을 수 있습니다.
var products = from p in _context.Products
where p.ProductTypeId == 1
orderby p.LowestPrice.HasValue descending,
p.LowestPrice
select p;
쿼리 구문에서 메서드 호출로의 변환에 대한 자세한 내용은 언어 사양을 참조하십시오. 진심으로. 읽어.
답변
문자열 값에 대한 해결책은 정말 이상합니다.
.OrderBy(f => f.SomeString == null).ThenBy(f => f.SomeString)
작동하는 유일한 이유는 첫 번째 표현식 OrderBy()
인 정렬 bool
값 때문입니다. true
/ false
. false
결과는 먼저 true
결과 (널링 가능 항목)를 따르고 널 ThenBy()
이 아닌 값을 알파벳순으로 정렬합니다.
따라서 다음과 같이 더 읽기 쉬운 것을 선호합니다.
.OrderBy(f => f.SomeString ?? "z")
SomeString
null 인 경우 는 대체되어 "z"
알파벳순으로 모든 것을 정렬합니다.
참고 :이 "z"
같은 z- 값보다 우선하기 때문에 이것은 궁극적 인 해결책이 아닙니다 zebra
.
업데이트 9/6/2016-@jornhd 의견에 관해서는, 정말 좋은 솔루션이지만 여전히 약간 복잡하므로 확장 클래스로 래핑하는 것이 좋습니다.
public static class MyExtensions
{
public static IOrderedEnumerable<T> NullableOrderBy<T>(this IEnumerable<T> list, Func<T, string> keySelector)
{
return list.OrderBy(v => keySelector(v) != null ? 0 : 1).ThenBy(keySelector);
}
}
그리고 간단하게 사용하십시오 :
var sortedList = list.NullableOrderBy(f => f.SomeString);
답변
이 상황에서 다른 옵션이 있습니다. 내 목록은 objList이며 주문해야하지만 null은 끝에 있어야합니다. 나의 결정:
var newList = objList.Where(m=>m.Column != null)
.OrderBy(m => m.Column)
.Concat(objList.where(m=>m.Column == null));
답변
나는 이것에 대한 LINQ 솔루션을 찾으려고했지만 여기의 답변에서 해결할 수 없었습니다.
내 최종 답변은 다음과 같습니다
.OrderByDescending(p => p.LowestPrice.HasValue).ThenBy(p => p.LowestPrice)
답변
나의 결정:
Array = _context.Products.OrderByDescending(p => p.Val ?? float.MinValue)
답변
이것은 확장 방법을 사용하고 있기 때문에 내가 생각 해낸 것입니다. 또한 내 항목은 문자열이므로 없습니다 .HasValue
.
.OrderBy(f => f.SomeString == null).ThenBy(f => f.SomeString)
메모리의 LINQ 2 개체와 함께 작동합니다. EF 또는 DB ORM으로 테스트하지 않았습니다.