Linq query with multiple OrderBy statements added to the loop

I have a method in webservice that has a parameter with which users can decide how they want to organize their results. This is a List(Of String) with the field names in the order they are sorted.

I know that I can order multiple columns normally by doing the following

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

However, in this case, this will not work, since I cannot bind the ThenBy function, because I add the sort order in the loop. To use ThenBy I need a collection of IOrderedQueryable . This is how I would like it to work

 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) xx).ToList() Return result 

This, of course, will not work, because OrderBy will replace any previous order. The only solution I can think of is to first order a list for some other variable, so I already have an IOrderedQueryable collection, but that seems like the wrong approach.

 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) xxFoo) Case "Bar" query = query.ThenBy(Function(x) xxBar) Case "Test" query = query.ThenBy(Function(x) xxTest) End Select Next Dim result = query.Select(Function(x) xx).ToList() Return result 
+7
source share
1 answer

You can write your own OrderByOrThenBy extension method that checks if this value is IOrderedQueryable , uses ThenBy if it is, and OrderBy otherwise. A little smelly, but not very difficult to do.

EDIT: C # sample (untested):

 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); } } 
+7
source

All Articles