Skip ThenBy on objects with a null value

I have a query that needs to be ordered as follows:

var list = new List<MonthClosureViewModel>(); var orderedList = list .OrderByDescending(x => x.Project) .ThenByDescending(x => x.ChargeLine) .ThenByDescending(x => x.DomesticSite) //<- x.DomesticSite might be null sometimes .ThenByDescending(x => x.ChargeSite) //<- x.ChargeSite might be null sometimes .ThenByDescending(x => x.RateGroup) .ThenByDescending(x => x.ApprovedHrs) .ThenByDescending(x => x.NotApprovedHrs); public class MonthClosureViewModel { public Project Project { get; set; } public ChargeLine ChargeLine { get; set; } public Site DomesticSite { get; set; } public Site ChargeSite { get; set; } public RateGroup RateGroup { get; set; } public decimal Rate { get; set; } public decimal ApprovedHrs { get; set; } public decimal NotApprovedHrs { get; set; } } 

But if any object is null (completely by design), this request fails. How can I put null values ​​at the end or skip the order if the object is null?

ADDED: as @ LasseV.Karlsen mentioned that I may have another problem. I actually got an ArgumentNullException , but the reason is not that some object was null (I saw it in the debugger and falsely thought that this was my problem). The real reason was that @ RaphaëlAlthaus mentioned that I did not implement IComparable<> in ANY of my classes in MonthClosureViewModel ...

After I have done this, everything will start working as intended, even if the object is null

+5
source share
2 answers

You are trying to sort by complex properties, which (as you noted) are a real problem.

To make this possible, you will need to either

  • implement IComparable<T> in your classes

  • use other OrderBy / OrderByDescending overloads that also take IComparer<TKey> as an argument ( msdn for OrderBy overloads)

  • Use the simple property of a complex property in an order by clause (with a null check. In this case, a null check becomes necessary to avoid a Null Reference Exception):

For instance:

 .OrderByDescending(x => x.Project == null ? string.Empty : x.Project.Name) 
+3
source

You need to define defaultSite and defaultChargeSite both less and more than all other objects in your class

 var list = new List<MonthClosureViewModel>(); var orderedList = list .Where(x => x != null); .OrderByDescending(x => x.Project) .ThenByDescending(x => x.ChargeLine) .ThenByDescending(x => x.DomesticSite==null?defaultSite:x.DomesticSite) //<- x.DomesticSite might be null sometimes .ThenByDescending(x => x.ChargeSite==null?defaultChargeSite:x.ChargeSite) //<- x.ChargeSite might be null sometimes .ThenByDescending(x => x.RateGroup) .ThenByDescending(x => x.ApprovedHrs) .ThenByDescending(x => x.NotApprovedHrs); 
+3
source

All Articles