我仍在学习 LINQ,并且有一项任务需要按四个属性对 Booking 对象进行分组,然后根据输入时间范围按每周间隔分组。
public class Booking
{
public string Group { get; set; }
public BookingType Type { get; set; }
public BookingStatus Status { get; set; }
public decimal Price { get; set; }
public bool Notification { get; set; }
public DateTime Date { get; set; }
}
假设我们有以下预订:
IList<Booking> Bookings = new List<Booking>
{
new Booking{Group = "Group1", Type = BookingType.Online, Status = BookingStatus.New, Price = 150, Date = new DateTime(2012,06,01)},
new Booking{Group = "Group1", Type = BookingType.Online, Status = BookingStatus.New, Price = 100, Date = new DateTime(2012,06,02)},
new Booking{Group = "Group1", Type = BookingType.Online, Status = BookingStatus.New, Price = 200, Date = new DateTime(2012,06,03)},
new Booking{Group = "Group2", Type = BookingType.Phone, Status = BookingStatus.Accepted, Price = 80, Date = new DateTime(2012,06,10)},
new Booking{Group = "Group2", Type = BookingType.Phone, Status = BookingStatus.Accepted, Price = 110, Date = new DateTime(2012,06,12)},
new Booking{Group = "Group3", Type = BookingType.Store, Status = BookingStatus.Accepted, Price = 225, Date = new DateTime(2012,06,20)},
new Booking{Group = "Group3", Type = BookingType.Store, Status = BookingStatus.Invoiced, Price = 300, Date = new DateTime(2012,06,21)},
new Booking{Group = "Group3", Type = BookingType.Store, Status = BookingStatus.Invoiced, Price = 140, Date = new DateTime(2012,06,22)},
};
这将导致最终打印输出中出现以下几行:
Week 22 Week 23 Week 24 Week 25 Week 26
May28-Jun3 Jun4-10 Jun11-17 Jun18-24 Jun25-Jul1
Group Type Status Cnt. Price Cnt. Price Cnt. Price Cnt. Price Cnt. Price
----------------------------------------------------------------------------------------------
Group1 Online New 3 450 0 0 0 0 0 0 0 0
Group2 Phone Accepted 0 0 1 80 1 110 0 0 0 0
Group3 Store Accepted 0 0 0 0 0 0 1 225 0 0
Group3 Store Invoiced 0 0 0 0 0 0 2 440 0 0
我创建了 2 个额外的类来表示一条可以包含任意周数的行:
public class GroupedLine
{
public string Group { get; set; }
public BookingType Type { get; set; }
public BookingStatus Status { get; set; }
public List<WeeklyStat> WeeklyStats { get; set; }
}
public class WeeklyStat
{
public DateTime WeekStart { get; set; }
public decimal Sum { get; set; }
public int Count { get; set; }
}
如果我有以下时间段:
var DateFrom = new DateTime(2012, 05, 28);
var DateTo = new DateTime(2012, 7, 01);
首先,我需要确定统计数据中需要哪些周:在本例中为第 22-26 周。
为此,我有以下代码:
var DateFrom = new DateTime(2012, 05, 28);
var DateTo = new DateTime(2012, 7, 01);
var firstWeek = GetFirstDateOfWeek(DateFrom, DayOfWeek.Monday);
IList<DateTime> weeks = new List<DateTime> { firstWeek };
while(weeks.OrderByDescending(w => w).FirstOrDefault().AddDays(7) <= DateTo)
{
weeks.Add(weeks.OrderByDescending(w => w).FirstOrDefault().AddDays(7));
}
现在,我需要一些 LINQ 魔法来按 4 个属性和聚合(预订计数和价格总和)进行分组。
我可以附上我明天到目前为止得到的 LINQ 的代码示例,因为我现在无法访问它。对不起,很长的帖子,希望我的意思很清楚。
编辑:2012-11-07 我必须稍微修改一下问题,以便分组的周仅包括那些实际上有数据的周。更新的示例输出:
May28-Jun3 Jun4-10 Jun18-24
Group Type Status Cnt. Price Cnt. Price Cnt. Price
---------------------------------------------------------------
Group1 Online New 3 450 0 0 0 0
Group2 Phone Accepted 0 0 1 80 0 0
Group3 Store Accepted 0 0 0 0 1 225
Group3 Store Invoiced 0 0 0 0 2 440
在这种情况下,在 6 月 11 日至 17 日和 6 月 25 日至 7 月 1 日期间没有预订,因此从结果中省略了它们。