Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LINQ Order By Descending with Null Values on Bottom [duplicate]

Tags:

I have this expression:

troubletickets = db.ServiceTickets.Include(t => t.Company).Include(t => t.UserProfile);
troubletickets.OrderByDescending(t => t.UserProfile != null ? t.UserProfile.FirstName : "ZZZ");

I have to check if UserProfile is null because if I don't I will get an error. The problem is, sometimes UserProfiles.FirstName can be null. When it is null, those values are placed at the top of the list when I order by both ascending and descending. E.g.

// Null, Null, Andy, Bill, Chris
// Null, Null, Chris, Bill, Andy

How can I alter this expression so that when I order by descending it returns something like this instead:

// Chris, Bill, Andy, Null, Null
like image 892
mdk09 Avatar asked Oct 03 '14 20:10

mdk09


2 Answers

You almost had it right:

troubletickets.OrderByDescending(t => t.UserProfile != null
                                      && t.UserProfile.FirstName != null
                                         ? t.UserProfile.FirstName
                                         : string.Empty);

string.Empty will always be the lowest string, so it will end up last in an OrderByDescending.

If you want something that works with both ascending and descending order, you'd have to sort in two steps:

troubletickets.OrderByDescending(t => t.UserProfile != null
                                      && t.UserProfile.FirstName != null)
              .ThenByDescending(t => t.UserProfile != null                // Or ThenBy
                                         ? t.UserProfile.FirstName
                                         : null);

This works because true > false.

like image 69
Lucas Trzesniewski Avatar answered Sep 18 '22 15:09

Lucas Trzesniewski


What you can do to handle it in the general case is to first order by whether or not the value is null, and then order based on the value itself as a tiebreaker.

troubletickets = troubletickets.OrderBy(t => t.UserProfile != null)
   .ThenByDescending(t => t.UserProfile);
like image 20
Servy Avatar answered Sep 16 '22 15:09

Servy