Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LINQ OrderBy versus ThenBy

Tags:

linq

Can anyone explain what the difference is between:

tmp = invoices.InvoiceCollection               .OrderBy(sort1 => sort1.InvoiceOwner.LastName)               .OrderBy(sort2 => sort2.InvoiceOwner.FirstName)               .OrderBy(sort3 => sort3.InvoiceID); 

and

tmp = invoices.InvoiceCollection               .OrderBy(sort1 => sort1.InvoiceOwner.LastName)               .ThenBy(sort2 => sort2.InvoiceOwner.FirstName)               .ThenBy(sort3 => sort3.InvoiceID); 

Which is the correct approach if I wish to order by 3 items of data?

like image 480
DazManCat Avatar asked Sep 21 '10 11:09

DazManCat


People also ask

What is difference between OrderBy and ThenBy in LINQ?

Generally, ThenBy method is used with the OrderBy method. The OrderBy() Method, first sort the elements of the sequence or collection in ascending order after that ThenBy() method is used to again sort the result of OrderBy() method in ascending order.

What is ThenBy in LINQ?

ThenBy<TSource,TKey>(IOrderedEnumerable<TSource>, Func<TSource,TKey>, IComparer<TKey>) Performs a subsequent ordering of the elements in a sequence in ascending order by using a specified comparer.

What is OrderBy in LINQ?

Sorts the elements of a sequence in ascending order according to a key. OrderBy<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>, IComparer<TKey>) Sorts the elements of a sequence in ascending order by using a specified comparer.

Is LINQ OrderBy ascending?

In LINQ, the OrderBy operator is used to sort the list/ collection values in ascending order. In LINQ, if we use order by the operator by default, it will sort the list of values in ascending order. We don't need to add any ascending condition in the query statement.


1 Answers

You should definitely use ThenBy rather than multiple OrderBy calls.

I would suggest this:

tmp = invoices.InvoiceCollection               .OrderBy(o => o.InvoiceOwner.LastName)               .ThenBy(o => o.InvoiceOwner.FirstName)               .ThenBy(o => o.InvoiceID); 

Note how you can use the same name each time. This is also equivalent to:

tmp = from o in invoices.InvoiceCollection       orderby o.InvoiceOwner.LastName,               o.InvoiceOwner.FirstName,               o.InvoiceID       select o; 

If you call OrderBy multiple times, it will effectively reorder the sequence completely three times... so the final call will effectively be the dominant one. You can (in LINQ to Objects) write

foo.OrderBy(x).OrderBy(y).OrderBy(z) 

which would be equivalent to

foo.OrderBy(z).ThenBy(y).ThenBy(x) 

as the sort order is stable, but you absolutely shouldn't:

  • It's hard to read
  • It doesn't perform well (because it reorders the whole sequence)
  • It may well not work in other providers (e.g. LINQ to SQL)
  • It's basically not how OrderBy was designed to be used.

The point of OrderBy is to provide the "most important" ordering projection; then use ThenBy (repeatedly) to specify secondary, tertiary etc ordering projections.

Effectively, think of it this way: OrderBy(...).ThenBy(...).ThenBy(...) allows you to build a single composite comparison for any two objects, and then sort the sequence once using that composite comparison. That's almost certainly what you want.

like image 75
Jon Skeet Avatar answered Oct 09 '22 12:10

Jon Skeet