按日期对项进行计数和分组的Linq查询

ff29svar  于 2023-01-18  发布在  其他
关注(0)|答案(4)|浏览(119)

我有一个Orders的集合,这些集合是从EF中提取的。每个Order都有一个订单日期:

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>。我坚持的一点是对SelectMany方法中可查询的Orders进行分组和求和。
OrderDateSummary类类似于:

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

因此,起始日期为01/01/2016,终止日期为03/01/2016的输出如下所示:

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

6yjfywim1#

正如我所看到的,你需要生成从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

sg2wtvxw

sg2wtvxw2#

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 ();

只是你应该用classstruct标记你的OrderDateSummary,并使这些属性为public或添加构造函数。
预期结果中的日期为04/01/2016,因此,我猜,您的结束时间是第4天,而不是第3天。

bgtovc5b

bgtovc5b3#

请尝试下面的代码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; }
    }
}
dw1jzc5e

dw1jzc5e4#

怎么样

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();

相关问题