我有以下类定义:
public class MyData
{
public DateTime Expiration { get; private set; }
public string Name { get; private set; }
public double Price { get; private set; }
public double Quantity { get; private set; }
}
我需要加上一份年份清单:
IEnumerable<int> years= Enumerable.Range(1, 20);
结果将最终显示在网格中,y轴代表Name
字段,x轴代表年份。每个单元格将是Quantity
和年份的汇总Price
* Name
。
我目前正在努力学习语法。我开始时将MyData
的实例加入到这些年份并按如下方式分组:
var myData = GetData();
var query = from data in myData
join year in years on (data.Expiration.Year - DateTime.Now.Year) + 1 equals year
group data by new { Year = (data.Expiration.Year - DateTime.Now.Year) + 1
, Name = data.Name } into grouped
select new {Name = grouped.Key.Name
, Year = grouped.Key.Year
, Value = grouped.Sum(d => d.Quanity * d.Price) };
这为我提供了根据需要汇总的数据,但显然排除了MyData
的所有实例都不包含匹配Expiration
的任何年份。
我似乎无法弄清楚如何修改我的查询以获取我需要的数据。一旦我得到了包含的年份,我的聚合就会崩溃,而且我有效地在所有年份中得到Price
的所有Quantity
的{{1}}的总和,而不是Name
在逐年的基础上。
答案 0 :(得分:7)
有一种方法可以在LINQ中保持连接,但这是真的 - 语法不是很清楚。您的查询将如下所示:
var query = from year in years
join data in myData
on year equals (data.Expiration.Year - DateTime.Now.Year) + 1
into year_data
from y_d in year_data.DefaultIfEmpty()
group y_d by new
{
Year = year,
Name = y_d == null ? "" : y_d.Name
}
into grouped
select new
{
Name = grouped.Key.Name,
Year = grouped.Key.Year,
Value = grouped.Sum(d => d == null ? 0 : d.Quantity * d.Price)
};
答案 1 :(得分:1)
您还可以采用不同的方法 - 而不是加入,首先选择所有年份并过滤掉您的数据,同时计算每个数据对象/年的聚合。像这样:
from year in years select new
{
Year = year,
Items = myData
.GroupBy(i => i.Name)
.Select(grouped => new
{
Name = grouped.Key,
Aggregate = grouped
.Where(d => (d.Expiration.Year - DateTime.Now.Year) + 1 == year)
.Sum(d => d.Price * d.Quantity)
})
};
答案 2 :(得分:0)
如果你无法解决问题......替换它......
为每个名称和年份构建MyData的虚拟条目,其中quantity = 0且price = 0
将它们放入列表并替换此行:
var query = from data in myData
这一行:
var query = from data in myData.Concat(dummyList)