简体   繁体   English

跳过然后在可空的对象上

[英]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. 但是如果任何对象为null(完全按设计),则此查询失败。 How can I put null values at the end or skip ordering if object is null? 如果object为null,我如何在结尾处放置空值或跳过排序?

ADDED: as @LasseV.Karlsen mentioned I might have ANOTHER problem. 添加: @ LasseV.Karlsen提到我可能有另一个问题。 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). 我真的得到了ArgumentNullException ,但原因并不是后面的某个对象是null (我在调试器中看到它并错误地认为这是我的问题)。 The real reason was as @RaphaëlAlthaus mentioned that I didn't implement IComparable<> at ANY of my classes in MonthClosureViewModel ... 真正的原因是@RaphaëlAlthaus提到我没有在MonthClosureViewModel任何类中实现IComparable<> ...

After I've done it everything start working as intended even if object is null 完成后,即使object为null ,一切都按预期开始工作

You'll need to define defaultSite and defaultChargeSite to be either smaller or larger than all the other objects in their class 您需要将defaultSitedefaultChargeSite定义为比其他类中的所有其他对象更小或更大

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 在你的类上实现IComparable<T>

  2. use other overloads of OrderBy / OrderByDescending, which take also an IComparer<TKey> as argument ( msdn for the OrderBy overload) 使用OrderBy / OrderByDescending的其他重载,它还将IComparer<TKey>作为参数(OrderBy重载的msdn

  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) : 在order by子句中使用complex属性的简单属性(使用null检查。在这种情况下,必须进行null检查以避免Null引用异常):

For example : 例如 :

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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