Linq OrderBy子列表

Dr *_*izo 2 c# linq sorting

我试图执行一个相当简单的顺序,但似乎正在努力如何去做.举个例子,我有这两个类.

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; }
}
Run Code Online (Sandbox Code Playgroud)

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

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();
Run Code Online (Sandbox Code Playgroud)

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

虽然我可以通过实现IComparable接口来解决这个问题,但我想知道是否可以这样做.我想如果我有这个代码(见下文)就好了.

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);
Run Code Online (Sandbox Code Playgroud)

干杯,DS.

为变量的命名道歉xyz,例如上面的示例:)可以复制和粘贴代码以获得操作乐趣.

编辑 - 更新以简化代码示例. - 成功排序后的结果预期

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
Run Code Online (Sandbox Code Playgroud)

所以我的超快选项应该是最好的,因为它是最便宜的,当然有最快的交货日期.

dbc*_*dbc 7

您可以使用Enumerable.Min()最早的日期挑选插槽,如下所示:

        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();
Run Code Online (Sandbox Code Playgroud)

要不就

        var query = deliveryMethods
            .OrderBy(x => x.Slots.Min(s => s.ExpectedDeliveryDate.Date))
            .ToList();
Run Code Online (Sandbox Code Playgroud)

请注意,Min()当输入序列为空并且最小化的类型是值类型时,将抛出异常.如果您想避免异常,可以这样做:

        var query2 = deliveryMethods
            .OrderBy(x => x.Slots.Min(s => (DateTime?)(s.ExpectedDeliveryDate.Date)))
            .ToList();
Run Code Online (Sandbox Code Playgroud)

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