我试图执行一个相当简单的顺序,但似乎正在努力如何去做.举个例子,我有这两个类.
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)
所以我的超快选项应该是最好的,因为它是最便宜的,当然有最快的交货日期.
您可以使用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具有空槽列表的对象将被排序到开头.