2012-05-11 26 views
7

私は、ユーザが結果をどのようにして注文するかを決めるパラメータを持つメソッドをWebサービスに用意しています。これは、並べ替える順番でフィールドの名前を持つList(Of String)です。ループ内に複数のOrderByステートメントが追加されたLinqクエリ

私はソート順を追加しているので、しかし、この場合には、これは私がチェーンThenBy機能をすることはできませんので、動作しません、私は通常、次

Dim test = Bars.OrderBy(Function(x) x.Foo) _ 
       .ThenBy(Function(x) x.Bar) _ 
       .ThenBy(Function(x) x.Test) 

を行うことで、複数の列に注文することができます知っていますループで。 ThenByを使用するには、IOrderedQueryableコレクションが必要です。これは、私はそれがOrderByは以前の順序を交換しますので、もちろんこれは動作しません

Dim sortColumns = {"Foo", "Bar", "Test"} 
Dim query = From b in Bars 
For each column in sortColumns 
    Select Case column 
     Case "Foo" 
      query = query.Orderby(Function(x) x.Foo) 
     Case "Bar" 
      query = query.Orderby(Function(x) x.Bar) 
     Case "Test" 
      query = query.Orderby(Function(x) x.Test) 
    End Select 
Next 

Dim result = query.Select(Function(x) x.x).ToList() 
Return result 

仕事をしたいだろうかです。私が考えることができる唯一の解決策は、他の変数のリストを最初に並べることです。すでにIOrderedQueryableコレクションがありますが、これは間違ったアプローチのようです。

Dim bars As New List(Of Bar) 
Dim sortColumns = {"Foo", "Bar", "Test"} 
Dim query = bars.Select(Function(x) New With {.Temp = 1, .x = x}) _ 
       .OrderBy(Function(x) x.Temp) 

For Each column In sortColumns 
    Select Case column 
     Case "Foo" 
      query = query.ThenBy(Function(x) x.x.Foo) 
     Case "Bar" 
      query = query.ThenBy(Function(x) x.x.Bar) 
     Case "Test" 
      query = query.ThenBy(Function(x) x.x.Test) 
    End Select 
Next 

Dim result = query.Select(Function(x) x.x).ToList() 
Return result  
+0

"のOrderByは以前の順序を交換します"。無理。 OrderByは以前の順序を保持しています...意味:安定した並べ替えです。また、意味:それは、前の順序を使用して、現在の順序付けの結びつきを破る。それでは:OrderBy(Foo).ThenBy(Bar).ThenBy(Test)はOrderBy(Test)と同じです.OrderBy(Bar).OrderBy(Foo) –

答えて

7

あなたは、値がすでにIOrderedQueryableであるかどうかをチェックしそうそうとOrderBy場合ThenByを使用して、独自の拡張メソッドOrderByOrThenByを書くことができます。やや臭いですが、やりにくいです。

EDIT:C#サンプル(未テスト):

public static class QueryableOrdering 
{ 
    public static IOrderedQueryable<TElement> OrderByOrThenBy<TElement, TKey> 
     (this IQueryable<TElement> source, 
     Expression<Func<TElement, TKey>> ordering) 
    { 
     if (source == null) 
     { 
      throw new ArgumentNullException("source"); 
     } 
     if (ordering == null) 
     { 
      throw new ArgumentNullException("ordering"); 
     } 
     var ordered = source as IOrderedQueryable<TElement>; 
     return ordered == null ? source.OrderBy(ordering) 
           : ordered.ThenBy(ordering); 
    } 
} 
+0

C#サンプルは問題ありません。 –

+0

@FreekBuurman:完全にテストされていませんが、私の編集を参照してください... –

+0

いいソリューションのようですね、ありがとう! –

関連する問題