2016-12-22 54 views
1

我想填充我的名單失蹤日期,他們沒有銷售LIST最大和最小日之間列表...將缺少的日期,使用LINQ

我已經定義了一類這樣的:

public class GroupedItem 
    { 
     public DateTime _Date { get; set; } 
     public int Sales { get; set; } 
    } 

而現在列表中填充這樣的:

var LineGraph = _groupedItems 
         .GroupBy(l => l._Date.Date) 
         .Select(cl => new GroupedItem 
         { 
          _Date = cl.Key, 
          Sales = cl.Sum(c=>c.Sales) 
         }) 
         .OrderBy(x => x._Date) 
         .Where(t => t._Date <= DateTime.Now && 
         t._Date >= DateTime.Now.Subtract(TimeSpan.FromDays(date_range))) 
         .ToList(); 

而且我不用它,輸出類似如下:

11th December 6 sales 
13th December 8 sales 
18th December 12 sales 
19th December 25 sales 

這是相當好的,但我想補充一點,在第一和最後日期之間缺少的日期,以便我能有一個這樣的輸出:

11th December 6 sales 
12th December 0 sales 
13th December 8 sales 
14th December 0 sales 
15th December 0 sales 
16th December 0 sales 
17th December 0 sales 
18th December 12 sales 
21st December 25 sales 

我如何能實現這與LINQ?

+2

我的大腦有一段艱難的時期,並不想在日期範圍內留下一份日期列表。 – EJC

+0

真的只是離開了嗎?我如何在LINQ中做到這一點,我從來沒有做過...... – User987

+1

我正在使用LinqPad目前的解決方案,堅持。它可以是左連接或工會。 – EJC

回答

4

This Post有一種基於範圍生成日期列表的方法。我認爲我們必須將日期列表組合到分組查詢中,因爲它看起來像您的查詢結果不包含0銷售日期的行。

var LineGraph = _groupedItems.Union(Enumerable.Range(1, date_range) 
      .Select(offset => new GroupedItem { _Date = DateTime.Now.AddDays(-(date_range)).AddDays(offset), Sales = 0})) 
         .GroupBy(l => l._Date.Date) 
         .Select(cl => new GroupedItem 
         { 
          _Date = cl.Key, 
          Sales = cl.Sum(c=>c.Sales) 
         }) 
         .Where(t => t._Date <= DateTime.Now && 
         t._Date >= DateTime.Now.Subtract(TimeSpan.FromDays(date_range))) 
         .OrderBy(x => x._Date) 
         .ToList(); 

更正爲包括今天和通過選擇後的順序。

+0

它在完美地添加缺失的日期方面起作用...是的,這是我還沒有想出的問題,也許它不包括範圍給出的第一個或最後一個日期? – User987

+1

今天想包括嗎? – EJC

+0

是的,我想 – User987

3

您可以生成日期的列表,並作出左加入lineGraph生成整個列表:

var minDate = lineGraph.Min(g => g.Date); 
var maxDate = lineGraph.Max(g => g.Date); 
var range = GetDateRange(minDate, maxDate); 

var result = from date in range 
      from item in lineGraph.Where(g => g.Date.Date == date) 
            .DefaultIfEmpty() 
      select new GroupedItem 
      { 
       Date = date, 
       Sales = item?.Sales ?? 0 
      }; 

使用此方法來生成日期範圍:

public static IEnumerable<DateTime> GetDateRange(DateTime startDate, DateTime endDate) 
{ 
    var date = startDate.Date; 

    while (date <= endDate.Date) 
    { 
     yield return date; 
     date = date.AddDays(1); 
    } 
} 

或者,你可以這樣做:

var min = _groupedItems.Min(g => g.Date); 
var max = _groupedItems.Max(g => g.Date); 
var range = GetDateRange(min, max).Select(d => new GroupedItem { Date = d, Sales = 0 }); 

然後對range.Concat(_groupedItems)而不是_groupedItems進行查詢。

+0

如果日期範圍進入過去1個月,這項工作是否可行?例如:十二月二十二日至十一月二十三日? – User987

+0

@ User987:使用「left join」或「contact」解決方案,在兩種情況下,日期範圍從'_groupedItems'出現的最早日期到最後日期,而不考慮'range_date'值。 –