LINQ查询在一段时间内按月分组记录

时间:2012-11-07 16:24:58

标签: c# linq

我正在寻找一些帮助来调整以下LINQ查询以返回接下来6个月内的所有日期,即使是那些没有记录在给定月份内的日期。

var maxDate = DateTime.Now.AddMonths(6);

var orders = (from ord in db.Items

where (ord.Expiry >= DateTime.Now && ord.Expiry <= maxDate)

group ord by new
    {
        ord.Expiry.Value.Year,
        ord.Expiry.Value.Month
    }
into g
select new ExpiriesOwnedModel
    {
        Month = g.Select(n => n.Expiry.Value.Month).First(),
        Quantity = g.Count()
    }).ToList();

我非常感谢有关如何以最佳方式实施此项目的任何帮助或指示。

3 个答案:

答案 0 :(得分:3)

我不确定它与您的数据库的互动程度如何,但我会像加入一样:

var firstDaysOfMonths = Enumerable.Range(0, 7).Select(i =>
    new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1).AddMonths(i));
var orders = firstDaysOfMonths.GroupJoin(
    db.Items,
    fd => fd,
    ord => new DateTime(ord.Expiry.Value.Year, ord.Expiry.Value.Month, 1),
    (fd, ords) => new { Month = fd.Month, Quantity = ords.Count() });

请注意,在你没有这个月的前一天(在这个月的第一天?),你可能会有一个额外的月份。

答案 1 :(得分:2)

从罗林的答案中被盗,如果您更喜欢群组联接的查询语法(我这样做):

var orders =
    from month in Enumerable.Range(0, 7)
        .Select(i => new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1).AddMonths(i))
    join ord in db.Items
        on month equals new DateTime(ord.Expiry.Value.Year, ord.Expiry.Value.Month, 1)
        into ords
    select new { month.Month, Quantity = ords.Count() };

答案 2 :(得分:0)

如果它与数据库不匹配,则替代:

var rawGroups = db.Items.Where(item.Expiry >= DateTime.Now && ord.Expiry <= maxDate)
                        .GroupBy(item => new
                           {
                            item.Expiry.Value.Year,
                            item.Expiry.Value.Month
                           }, g => new ExpiriesOwnedModel()
                          {
                            Month = g.Key.Month,
                            Quantity = g.Count()
                          }).ToDictionary(model => model.Month);

var result = Enumerable.Range(DateTime.Now.Month,6)
                       .Select(i => i > 12 ? i - 12 , i)
                       .Select(i => rawGroups.Keys.Contains(i) ?
                                    rawGroups[i] :
                                    new ExpiriesOwnedModel() 
                                    { Month = i , Quantity = 0 });