2017-05-02 3 views
0

LINQ에서 동시에 여러 열을 기반으로 정렬하려고합니다.여러 차례 ThenBy를 순서없이 직접 사용하십시오.

이 정렬 된 목록을 달성하려면 첫 번째 열에 SortBy을 사용하고 ThenBy을 여러 개 사용하여 OrderBy의 결과를 다른 열로 정렬해야합니다.

는 그러나 문제는 내가 어떤 ThenBy 사용에 순서 (들)을하지 않아도됩니다 사용자가 첫 번째 열을 선택하고 내가 OrderBy에 매개 변수로이 열을 사용하고 나머지 열이 ThenBy에 매개 변수이기 때문이다. 적절한 익명 데이터 유형을 얻을 수

DatabaseEntityContext context = new DatabaseEntityContext(); 

및 쿼리 데이터 :

dynamic result; 

는 다음과 같은 개체 모델을 만들 :

그래서 내가 처음처럼 동적 전역 변수를 선언

var query1 = db.context.Select(x => new { Column1 = x.Column1, Column2 = x.Column2, 
Column3 = x.Column3, Column4 = x.Column4, Column5 = x.Column5 }).ToList(); 

    var query2 = query1.Select(x => new { Column1 = x.Column1, Column2 = x.Column2, 
Column3 = x.Column3, TotalColumn = x.Column4 + "-" + x.Column5 }).ToList(); 

마지막으로 query2result을 지정합니다. 0

result = query2; 
((IEnumerable<dynamic>)result) 에 내가 캐스팅 result에 LINQ 기능을 사용하지만, 일이 어떤 ThenBy 확장이없는이 캐스트의 결과이며 목록이 이미 정렬 된 수 있기 때문에 내가 먼저 OrderBy을 사용할 수 없습니다 다른 열을 추가하고 이전에 정렬 된 목록의 결과에 따라 다시 정렬하려면 ThenBy을 사용해야합니다. 내 문제가

, 나는 ThenBy에서 사용하는 여러 요인이 있지만 내가 OrderBy 첫째, 다음 OrderByThenBy를 사용한다이 때문에 정렬 할 수 없습니다 내가 직접 ThenBy을 사용할 수 없습니다.

그래서 이전에 주문한 목록에 ThenBy을 어떻게 직접 사용할 수 있습니까? 업데이트 1

: 는 @Patrick 호프만에 따르면 내가 좋아하는 IOrderedQueryable 내 캐스트 유형을 변경 한 :

result = ((IOrderedQueryable<dynamic>)result).ThenBy(x => x.MyDynamicField).ToList(); 

하지만 그것은 나에게 "x.MyDynamicField"에 컴파일 오류가 제공하지 않습니다 :

식을 트리에 동적 작업이 포함되지 않을 수 있습니다.

또한 IOrderedEnumerable을 테스트하지만 InvalidCastException 오류 제공합니다

'System.Collections.Generic.List 유형 의 개체를 캐스팅 할 수 없습니다 1[<>f__AnonymousType1 5 [선택 System.String, 선택 System.String, System.DateTime, System.TimeSpan을 , System.Nullable 1[System.Int32]]]' to type 'System.Linq.IOrderedEnumerable 1 [System.Object] '입니다.

+0

'결과'가 'IEnumerable'또는 'IOrderedEnumerable'인지 확인해야하는 것처럼 들립니다. 하지만 알기가 어렵습니다. 'ToList' 전에 주문이 완료되었다는 것을 말하면, 나는 당신에게 말하기가 싫지만'ThenBy' 호출을 추가하기 전에 다시 주문해야합니다. – juharr

답변

2

ThenByIOrderedQueryable이 아닌 IEnumerable의 확장 방법입니다. 당신이 ThenBy를 호출 할 경우, 당신은 IOrderedQueryable에 캐스팅해야합니다

var r = ((IOrderedQueryable<dynamic>)result).ThenBy(...); 
, 당신도 유형을 확인하려면이 옵션을 확장 할 수 있습니다 주석 juharr으로

다음 선택 중 하나 ThenBy 또는 OrderBy, 필터링하기 위해 동일한 술어를 사용하여 . 대신 당신이 할 수 OrderBy/ThenBy를 사용

+0

@PatrickHoffman 오류가 발생합니다. 나는 당신의 해결책에 따라 질문을 업데이트했다. –

+1

여전히 속성 값을 가져 오기위한 리플렉션이 있습니다. –

+0

어떻게? 그것은 나에게 "표현식 트리는 동적 인 연산을 포함 할 수 없다"라는 오류를 준다! –

1

: 이미 다른 OrderBy (그 때 ThenBy를 사용합니다) 여부가있는 경우

public static class QueryableOrderBy 
{ 
    public static IOrderedQueryable<TSource> OrderBySimple<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector) 
    { 
     var ordered = source as IOrderedQueryable<TSource>; 

     if (source != null) 
     { 
      return ordered.ThenBy(keySelector); 
     } 

     return source.OrderBy(keySelector); 
    } 

    public static IOrderedQueryable<TSource> OrderByDescendingSimple<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector) 
    { 
     var ordered = source as IOrderedQueryable<TSource>; 

     if (source != null) 
     { 
      return ordered.ThenByDescending(keySelector); 
     } 

     return source.OrderByDescending(keySelector); 
    } 
} 

이 방법은 "분석"합니다.

+0

이 경우에 동적 변수를 인식하지 못하기 때문에 코드에서 IOrderedQueryable을 사용하는 데 오류가 있습니다. IOrderedQueryable 사용에 대한 내 질문을 업데이트했습니다. –