2016-03-18 48 views
1

我有一個從EF中提取的Orders的集合。每個Order有訂單日期:Linq查詢按日期統計和分組項目

public class Order { 
    public DateTime Date { get; set; } 
    public int Id { get; set; } 
} 

我希望能夠運行一個查詢在特定日期範圍返回訂單的數量每一天。查詢方法應該是這個樣子:

public class ICollection<OrderDateSummary> GetOrderTotalsForDateRange(DateTime startDate, DateTime endDate) { 

     var orderDateSummary = Set.SelectMany(u => u.Orders) // ..... grouping/totalling here?! 

     return orderDateSummary; 
} 

有關信息,Set居然是返回一個用戶聚合根的存儲庫的一部分,所以Set類型是DbSet<User>我堅持上分組和彙總的位Orders可從SelectMany方法查詢。

的OrderDateSummary類的樣子:

public OrderDateSummary { 
     DateTime Date { get; set; } 
     int Total { get; set; } 
} 

因此,輸出的2016年1月1日開始日期和2016年3月1日結束日期看起來是這樣的:

Date   Total 
=================== 
01/01/2016  10 
02/01/2016  2 
03/01/2016  0 
04/01/2016  12 
+0

什麼是你的問題?無法看到問題或可能發生的任何錯誤。 – HimBromBeere

+0

var x = orderDateSummary = Set.SelectMany(u => u.Orders).where(x => x.startdate> = sdate && x.Enddate <= edate).select(x => x.total) –

+0

您是否還需要零行'03/01/2016 - 0'? –

回答

1

,我可以看到你需要生成範圍內的所有日期從startend。然後計算每個日期的訂單總數。

DateTime start = new DateTime(2016, 1, 1); 
DateTime end = new DateTime(2016, 1, 4); 
Enumerable 
    .Range(0, 1 + (end - start).Days) 
    .Select(x => start.AddDays(x)) 
    .GroupJoin(Set.SelectMany(u => u.Orders), 
     dt => dt, o => o.Date.Date, 
     (dt, orders) => new OrderDateSummary { Date = dt, Total = orders.Count() }) 
    .ToList(); 

結帳working example on Ideone

+0

這看起來像是最好的解決方案,因爲它應該在沒有訂單的任何日子中添加爲零。但是,當我使用查詢時,它會在所有日期內返回零計數總數? – Graham

+0

@格拉漢姆,檢查編輯。改變了'o => o.Date' - >'o => o.Date.Date'。我以爲你沒有時間訂購日期,但如果你說你得到零,這可能是原因。 –

2
var startDate = new DateTime (2016, 1, 1); 
var endDate = new DateTime (2016, 1, 4); 

Set.SelectMany(u => u.Orders). 
    Where (order => startDate <= order.Date && order.Date <= endDate) // If filter needed 
    GroupBy (order => order.Date, (date, values) => 
     new OrderDateSummary() { 
      Date = date, 
      Total = values.Count() 
     }). 
    OrderBy (summary => summary.Date). 
    ToList(); 

只要你應當標註你的OrderDateSummaryclassstruct,讓這些屬性public或添加構造函數。

而且你在預期結果中有一個日期04/01/2016,所以,我想你的結束時間是第4次而不是第3次。

+1

您可以隨時在末尾添加「ToList()」。 –

1

如何低於約

List<OrderDateSummary> Result = OrderList  
    .Where(x => x.Date >= startDate && x.Date <= endDate) 
    .GroupBy(x => x.Date) 
    .Select(z => new OrderDateSummary(){ 
      Date = z.Key, 
      Total = z.Count() 
    }).OrderBy(d=> d.Date).ToList(); 
0

try代碼是LINQ

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Data; 

namespace ConsoleApplication82 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      List<OrderDateSummary> orderSummary = null; 

      DataTable dt = new DataTable(); 
      dt.Columns.Add("id", typeof(int)); 
      dt.Columns.Add("date", typeof(DateTime)); 
      dt.Columns.Add("amount", typeof(decimal)); 

      dt.Rows.Add(new object[] { 1, DateTime.Parse("1/1/16"), 1.00 }); 
      dt.Rows.Add(new object[] { 2, DateTime.Parse("1/1/16"), 2.00 }); 
      dt.Rows.Add(new object[] { 3, DateTime.Parse("1/2/16"), 3.00 }); 
      dt.Rows.Add(new object[] { 4, DateTime.Parse("1/2/16"), 4.00 }); 
      dt.Rows.Add(new object[] { 5, DateTime.Parse("1/2/16"), 5.00 }); 
      dt.Rows.Add(new object[] { 6, DateTime.Parse("1/3/16"), 6.00 }); 
      dt.Rows.Add(new object[] { 7, DateTime.Parse("1/3/16"), 7.00 }); 

      orderSummary = dt.AsEnumerable() 
       .GroupBy(x => x.Field<DateTime>("date")) 
       .Select(x => new OrderDateSummary() { Date = x.Key, Total = x.Count() }) 
       .ToList(); 
     } 

    } 
    public class OrderDateSummary { 
     public DateTime Date { get; set; } 
     public int Total { get; set; } 
    } 
}