2012-11-21 2 views
8

최종 사용자가 반환 된 보고서의 정렬 순서에 대해 여러 필드를 선택할 수있는보고 인터페이스가 있습니다. 내가 겪고있는 문제는 정렬 필드 목록을 반복하고 있기 때문에 OrderBy/ThenBy 메서드를 실제로 연결할 수 없다는 것입니다. 나는 이런 식으로 뭔가를 생각하고 있어요 :프로그래밍 방식으로 LINQ/Entity Framework를 사용하여 OrderBy/ThenBy 체인으로 연결

foreach (string sort in data.SortParams) 
{ 
    switch (sort) 
    { 
     case "state": 
      query = query.ThenBy(l => l.RegionCode); 
      break; 
     case "type": 
      query = query.ThenBy(l => l.Type); 
      break; 
     case "color": 
      query = query.ThenBy(l => l.Color); 
      break; 
     case "category": 
      query = query.OrderBy(l => l.Category); 
      break; 
    } 
} 

(참고 :. 나는이 단순화하기위한 첫 번째 정렬 항목입니다 여부를 결정하는 스위치를 제거했습니다) 컬렉션을 반복하는 방법에 대한

어떤 생각 정렬 순서를 결정하려면?

답변

15

당신은 당신이 처음 "씨"있는 OrderBy 사용하는 경우 당신이 원하는 것을 할 수 있습니다 : 당신이 만들 수 OrderBy를 호출 할 필요가

편집을 IOrderedEnumerable (또는 IOrderedQueryable) 첫 ThenBy 절을 부착하기 전에 :

var orderedQuery = query.OrderBy(l => 0); 
foreach (string sort in data.SortParams) 
{ 
    switch (sort) 
    { 
     case "state": 
      orderedQuery = orderedQuery.ThenBy(l => l.RegionCode); 
      break; 
     case "type": 
      orderedQuery = orderedQuery.ThenBy(l => l.Type); 
      break; 
     case "color": 
      orderedQuery = orderedQuery.ThenBy(l => l.Color); 
      break; 
     case "category": 
      orderedQuery = orderedQuery.ThenBy(l => l.Category); 
      break; 
    } 
} 
query = orderedQuery; // cast back to original type. 

좀 더 유연한 체크 아웃을 원하시면 this answer

+0

광고 소재. 쿼리 성능에 영향을 미치는지 확인해야합니다. 인덱스 사용을 막을 수 있습니다. – usr

+1

이것은 나를 위해 매력처럼 일했습니다. 처음에는 위와 똑같은 코드를 가지고 있었지만 첫 번째 OrderBy()에 대한 기본 열을 선택해야했습니다. 대신 0을 넣을 수 있는지 몰랐습니다. 0은 궁극적 인 SQL 쿼리가 모든 행에 대해 값이 0 인 추가 열을 가져온 다음 더미 정렬을 달성하여 해당 행별로 정렬 한 다음 연결된 'ThenBy()'의 모든 열을 적용합니다 '당신이 더했다. 감사! – BeemerGuy

+0

'OrderBy (l => 0)'을 호출 할 때'ArgumentOutOfRangeException'이 발생합니다. [Here] (https://pastebin.com/raw/TZQ9g8Es)는'StackTrace'입니다. – Shimmy

-1

하나의 Linq 쿼리를 모두 사용하는 것이 가독성 측면에서 최상의 옵션은 아닙니다. IQueryable을 사용하여 메모리에서 쿼리를 생성합니다. 비슷한 종류의 switch 문 (IQueryable과 함께)을 사용하고 마지막으로 .ToList (예 : 열거)를 수행하여 서버에서 원하는 쿼리를 실행합니다.

+1

감사합니다. 그러나 'query' var는 사실 IQueryable입니다. 문제는 OrderBy 및 ThenBy 명령입니다. ThenBy는 OrderBy에 처음 연결될 때만 사용할 수있는 것처럼 보입니다. – acullen72

+1

아래로 투표에 대한 expalin 케어! ???????? – daehaai

1

질문에 명시된 방법이 동일한 문제를 해결하기 위해 이러한 확장 메서드 만에 이전의 발현을 확인

foreach (string sort in data.SortParams) 
{ 
    switch (sort) 
    { 
     case "state": 
      query = query.AppendOrderBy(l => l.RegionCode); 
      break; 
     case "type": 
      query = query.AppendOrderBy(l => l.Type); 
      break; 
     case "color": 
      query = query.AppendOrderBy(l => l.Color); 
      break; 
     case "category": 
      query = query.AppendOrderBy(l => l.Category); 
      break; 
    } 
} 

비고 :

public static class QueryableExtensions 
{ 
    public static IOrderedQueryable<T> AppendOrderBy<T, TKey>(this IQueryable<T> query, Expression<Func<T, TKey>> keySelector) 
     => query.Expression.Type == typeof(IOrderedQueryable<T>) 
     ? ((IOrderedQueryable<T>) query).ThenBy(keySelector) 
     : query.OrderBy(keySelector); 

    public static IOrderedQueryable<T> AppendOrderByDescending<T, TKey>(this IQueryable<T> query, Expression<Func<T, TKey>> keySelector) 
     => query.Expression.Type == typeof(IOrderedQueryable<T>) 
      ? ((IOrderedQueryable<T>)query).ThenByDescending(keySelector) 
      : query.OrderByDescending(keySelector); 
} 

질문의 코드는 다음에 리팩토링 할 수 표현 트리를 사용하여 OrderBy 또는 ThenBy을 사용하려면 다른 표현식을 사용할 수 없습니다. 그 문제를 해결하고 싶다면, 그냥 오버 헤드를 추가 할 수있는 트리 전체를 따라 가야합니다. :)

관련 문제