2016-03-18 46 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; } 
    } 
}