简体   繁体   中英

Skip ThenBy on nullable objects

I have a query which should be ordered like that:

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 (totally by design) this query fails. How can I put null values at the end or skip ordering if object is null?

ADDED: as @LasseV.Karlsen mentioned I might have ANOTHER problem. I really got ArgumentNullException , but the reason was not behind some object were null (I saw it in debugger and falsely thought that it was my problem). The real reason was as @RaphaëlAlthaus mentioned that I didn't implement IComparable<> at ANY of my classes in MonthClosureViewModel ...

After I've done it everything start working as intended even if object is null

You'll need to define defaultSite and defaultChargeSite to be either smaller or larger than all the other objects in their 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);

You try to order by complex properties, which is (as you mentionned) the real problem.

To make it possible you'll have to, either

  1. implement IComparable<T> on your classes

  2. use other overloads of OrderBy / OrderByDescending, which take also an IComparer<TKey> as argument ( msdn for the OrderBy overload)

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

For example :

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM