我已经编写了一个解决方案,它基本上添加了缺少日期,并将我的集合中该日期的销售属性设置为0,这样它就像这样:
int range = Convert.ToInt32(drange);
var groupedByDate = tr.Union(Enumerable.Range(1, Convert.ToInt32(range))
.Select(offset => new MyClassObject
{
Date = DateTime.Now.AddDays(-(range)).AddDays(offset),
Sales = 0
})).GroupBy(x => x.Date)
.Select(item => new MyClassObject
{
Sales = item.Sum(x => x.Sales),
Date = item.Key
})
.OrderBy(x => x.Date)
.ToList();
第一个解决方案,其中来自DB的日期被分组并且它们丢失了如下所示:
var groupedByDate = tr
.GroupBy(x => x.TransactionDate.Date)
.Select(item => new MyClassObject
{
Sales = item.Sum(x => x.QuantityPurchased),
Date = item.Key.ToString("yyyy-MM-dd")
})
.OrderBy(x => x.Date)
.ToList();
我不喜欢我在第一个解决方案中做到的方式,代码看起来非常混乱,我真的相信它可以用更好的方式编写。
有人可以帮我解决这个问题吗?
P.S。我所展示的第一个解决方案效果很好,但我想写一些更好看的东西,它看起来更漂亮(我写的第一个解决方案)......
答案 0 :(得分:2)
如何生成日期范围,然后使用原始查询的结果保持连接。而不是在没有匹配时将Sales
设置为0
。
int range = 2;
var startDate = DateTime.Now;
var dates = Enumerable.Range(1, range)
.Select(offset => startDate.AddDays(-offset).Date);
var groupedByDate = from date in dates
join tmp in groupedByDate on date equals tmp.Date into g
from gr in g.DefaultIfEmpty()
select new MyClassObject
{
Sales = gr == null ? 0 : gr.Sales,
Date = date
};
答案 1 :(得分:1)
以下是执行此操作的简便方法:
var lookup = tr.ToLookup(x => x.TransactionDate.Date, x => x.QuantityPurchased);
var quantity = lookup[new DateTime(2017, 6, 29)].Sum();
如果你想要一系列日期,那就是这样:
var startDate = new DateTime(2017, 6, 1)
var query =
from n in Enumerable.Range(0, 30)
let TransactionDate = startDate.AddDays(n)
select new
{
TransactionDate,
QuantityPurchases = lookup[TransactionDate].Sum(),
};
简单。