2012-05-11 22 views
7

Web servisinde, kullanıcıların sonuçlarını nasıl sıralamak istediğine karar verebilecek parametresi olan bir yöntem var. Bu, alanların sırasını sıralamak istedikleri sıraya sahip olan List(Of String)'dur.Bir döngüde eklenen birden fazla OrderBy ifadesi ile Linq sorgusu

ben sıralama emir değil zincir ThenBy işlevi ekliyorum çünkü beri normalde bu işe yaramaz bu durumda Ancak şu

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

yaparak birden çok sütun üzerinde sipariş edebilirsiniz biliyorum bir döngüde. ThenBy'u kullanmak için IOrderedQueryable koleksiyonuna ihtiyacım var. Bu Ben OrderBy önceki sıralamasını değiştirecek olmasından elbette bu işe yaramaz

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 

çalışmasını isterim nasıl. Düşünebildiğim tek çözüm, önce diğer bir değişkende listeyi sıralamaktır, bu yüzden zaten bir IOrderedQueryable koleksiyonum var ama bu yanlış bir yaklaşım gibi görünüyor.

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 önceki sipariş yerini alacak". Gerçek dışı. OrderBy önceki siparişleri korur ... anlam: istikrarlı bir yeniden sıralamadır. Ayrıca anlam: mevcut siparişteki bağları koparmak için önceki siparişi kullanır. Yani: OrderBy (Foo) .ThenBy (Bar) .ThenBy (Test) OrderBy ile aynıdır (Test) .OrderBy (Bar) .OrderBy (Foo) –

cevap

7

Sen, değer zaten bir IOrderedQueryable olup olmadığını kontrol eder, aksi takdirde bu yüzden ve OrderBy eğer ThenBy kullanan kendi uzantısı yöntemi OrderByOrThenBy yazabiliriz. Biraz koklamak ama yapmak çok zor değil.

DÜZENLEME: C# örnek (denenmemiş):

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

Bir C# örnek iyi olurdu, ben dönüşüm kendim yapabilirim. –

+0

@FreekBuurman: Tamamen denenmemiş, ama benim düzenleme gör ... –

+0

Bu hoş bir çözüm gibi görünüyor, teşekkürler! –