Linq OrderBy通过子列表 [英] Linq OrderBy Sub List

查看:45
本文介绍了Linq OrderBy通过子列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试执行一个相当简单的命令,但是似乎在如何去做上很挣扎.例如,我有这两个类.

I am trying to perform a fairly simple order by but seem to be struggling on how to go about doing it. Take for instance I have these two classes.

public class Method
{
    public int Id { get; set; }

    public string Name { get; set; }

    public decimal Price { get; set; }

    public List<Slot> Slots { get; set; }
}

public class Slot
{
    public DateTime ExpectedDeliveryDate { get; set; }
}

使用下面的代码,我想按最便宜的方式订购,然后按最快的交货日期订购.

Using the code below I want to order by the cheapest option and then by the quickest delivery date.

var methods = new List<Method>();

methods.Add(new Method { Id = 1, Name = "Standard", Price = 0M, Slots = new List<Slot> { new Slot { ExpectedDeliveryDate = DateTime.Now.AddDays(5).Date } } });
methods.Add(new Method { Id = 2, Name = "Super Fast Next Day", Price = 0M, Slots = new List<Slot> { new Slot { ExpectedDeliveryDate = DateTime.Now.AddDays(1).Date } } });

var b = methods.OrderBy(x => x.Price)
    .ThenBy(y => y.Slots.OrderBy(t => t.ExpectedDeliveryDate.Date)
        .ThenBy(t => t.ExpectedDeliveryDate.TimeOfDay))
            .ToList();

我在这里遇到的麻烦是,我收到一个运行时错误,指出至少一个对象必须实现IComparable".

The trouble I am getting here is that I am getting a runtime error stating "At least one object must implement IComparable".

尽管我可以通过实现IComparable接口来解决此问题,但我想知道是否有可能做到这一点.我想好像我有这段代码(见下文)可以正常工作.

Although I can fix this by implementing the IComparable interface, I was wondering if it was possible to do this. I imagine there is as if I had this code (see below) it works fine.

var slots = new List<Slot>();

slots.Add(new Slot { ExpectedDeliveryDate = DateTime.Now.AddDays(5).Date });
slots.Add(new Slot { ExpectedDeliveryDate = DateTime.Now.AddDays(1).Date });
slots.Add(new Slot { ExpectedDeliveryDate = DateTime.Now.AddDays(3).Date });
slots.Add(new Slot { ExpectedDeliveryDate = DateTime.Now.Date });

var d = slots.OrderBy(x => x.ExpectedDeliveryDate);

干杯,DS.

如上例中的xyz这样的变量命名道歉:)可以复制并粘贴代码以提高操作乐趣.

Apologies for the naming of variables such as xyz in example above :) Code can be copied and pasted for manipulation pleasure.

编辑 -更新以简化代码示例. -对结果的期望是在成功排序之后

EDIT - Updated to simplify code example. - Expectation of result would be after successful sorting

Input
  ID     Name            Price    Slot
  1      Standard        0        DateTime.Now.AddDays(5).Date
  2      Super Fast      0        DateTime.Now.Date

Output
  2      Super Fast      0        DateTime.Now.Date  
  1      Standard        0        DateTime.Now.AddDays(5).Date

因此,我的超级快选项应该是最优先的选择,因为它最便宜,而且交货日期当然也最快.

So my super fast option should be top due to it being the cheapest and of course has the quickest delivery date.

推荐答案

您可以使用

You can use Enumerable.Min() to pick out the slot with the earliest date, like so:

        var query = deliveryMethods
            .OrderBy(x => x.Slots.Min(s => s.ExpectedDeliveryDate).Year)
            .ThenBy(x => x.Slots.Min(s => s.ExpectedDeliveryDate).Month)
            .ThenBy(x => x.Slots.Min(s => s.ExpectedDeliveryDate).Date)
            .ToList();

或者,只是

        var query = deliveryMethods
            .OrderBy(x => x.Slots.Min(s => s.ExpectedDeliveryDate.Date))
            .ToList();

请注意,当输入序列为空并且最小化的类型为值类型时,Min()将引发异常.如果要避免该异常,可以执行以下操作:

Do be aware that Min() will throw an exception when the input sequence is empty and the type being minimized is a value type. If you want to avoid the exception, you could do this:

        var query2 = deliveryMethods
            .OrderBy(x => x.Slots.Min(s => (DateTime?)(s.ExpectedDeliveryDate.Date)))
            .ToList();

通过将DateTime转换为可为空的值,Min()将为空序列返回null,并且具有空槽位列表的Method对象将被排序到开头.

By converting the DateTime to a nullable, Min() will return a null for an empty sequence, and Method objects with empty slot list will get sorted to the beginning.

这篇关于Linq OrderBy通过子列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆