将数据分组并为图表返回序列的LINQ
本文关键字:返回 LINQ 数据 | 更新日期: 2023-09-27 18:13:09
假设我们有一个简化的Orders实体,具有以下属性:Id (int, PK), orderDate (datetime,非null)和productCategory (string,非null)。
LINQ to Entities查询返回每个类别的订单计数,按月分组,过去12个月,按年,按月订购,该是什么?
输出应该是这样的,为了将其作为Highcharts折线图的级数传递,使用JQuery.getJSON()
:
[{
name: 'Dairy',
data: [23, 27, 32, 44, 21, 30, 11, 0, 9, 24, 3, 19]
},
{
name: 'Frozen',
data: [11, 4, 0, 6, 8, 10, 17, 24, 18, 8, 23, 10]
}]
即每个类别有12个值,包括0。
这似乎可以工作:
var orders = from o in orderList.ToList().Where(x => x.orderDate >= DateTime.Now.AddYears(-1)).GroupBy(x => x.productCategory)
select new {
name = o.Key,
data = ((Func<int[]>)(() => {
var months = new int[12];
for (int i = 0; i < 12; i++) {
months[i] = o.Where(x => x.productCategory == o.Key && x.orderDate.Month == i).Count();
}
return months;
}))()
};
首先,我们筛选日期在去年的订单。然后按productCategory字段对结果进行分组。从这个分组中,我们创建一个匿名投影类。这里,我们将name字段设置为分组键(类别)。为了填充data字段,我们使用一个匿名函数枚举每个月,并计算与我们分组的月号和产品类别匹配的每条记录。
这允许我们输入没有数据的月份的0计数
var months = Enumerable.Range(1, 12);
var max = DateTime.Now.AddYears(-1);
var result = data.Where(d => d.OrderDate >= max)
.GroupBy(d => d.ProductCategory)
.Select(g =>
new
{
Name = g.Key,
Data =(
from m in months
join d in
g.OrderBy(gg => gg.OrderDate.Year)
.ThenBy(gg => gg.OrderDate.Month)
.GroupBy(gg => gg.OrderDate.Month)
on m equals d.Key into gj
from j in gj.DefaultIfEmpty()
select j.Key != null ? j.Count() : 0)
}).ToArray();