tags:

views:

78

answers:

1

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?

+8  A: 

You should definitely use ThenBy rather than multiple OrderBy calls. (I assume one of the snippets in your question was meant to use ThenBy. At the time of this writing, the two snippets are identical.)

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
      order by 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.

Jon Skeet
Thats what I thought but, for some reason the OrderBy,ThenBy,ThenBy does not seem to be sorting correctly so I wondered if I was using it correctly.
DazManCat