【问题标题】:Linq / Entity Framework - how to group by date with range [closed]Linq / Entity Framework - 如何按日期分组[关闭]
【发布时间】:2015-08-03 15:29:00
【问题描述】:

我有一个包含以下数据的“案例”表:

ID |  OpenDate  |  CloseDate
-----------------------------
1  | 2015-01-01 | 2015-01-02
2  | 2015-01-02 | 2015-01-03
3  | 2015-01-03 | 2015-01-03

我想为指定的日期范围创建一个 linq 查询,以查看指定范围内每个日期的未结案件的计数,以便我可以创建未结案件的时间线图。一个案例在其 OpenDate、CloseDate 和其间的所有日期都被视为未结案。例如,如果一个案例于 1 月 1 日开立并于 1 月 3 日结束,则将在 1 月 1 日、2 日和 3 日计算。

如果我要查询的日期范围是 2015 年 1 月 1 日到 2015 年 1 月 4 日,以下是我希望退出查询的结果示例。

Date       |  Count
--------------------
2015-01-01 | 1
2015-01-02 | 2
2015-01-03 | 2
2015-01-04 | 0

如果不对报告日期范围内的每个日期进行 linq 查询,我似乎找不到一种简单的方法(例如,60 天的范围将需要对数据库进行 60 次查询)。是否有使用 EF 从一个查询中获取这些结果的简单解决方案?

编辑 修正了计数错字。同样作为澄清,一个案件被认为是开放的,直到结束日期结束。例如,ID 2 应计入 1 月 2 日和 3 日。

【问题讨论】:

  • 您的预期结果没有多大意义。 2015-01-02 是多少 22015-01-031
  • I can't seem to find an easy way to do this我们也想看看艰难的路。
  • @MarcinJuraszek OP 正在寻求回答这个问题——对于给定的日期,第一个表中有多少范围包含该记录?
  • @ZevSpitz 是的,这就是我所追求的 - 在一个范围内的每个日期有多少个案件被认为是未结的。因此,例如,如果一个案例的开放日期为 1 月 1 日,结束日期为 1 月 3 日,它将增加 1 月 1 日、2 日和 3 日的计数。理论上我可以在请求的范围内对每个日期进行循环,但是我希望将其简化为一个查询,以避免多次调用数据库。

标签: c# linq entity-framework


【解决方案1】:

也许试试这个。首先生成您感兴趣的本地日期序列:

var startDate = new DateTime(2015,1,1);
var dates = Enumerable.Range(0,300).Select(offset => startDate.AddDays(offset));

然后,试试这个(dcx 是您的数据上下文,CaseRanges 对应于您的第一个表):

var query = from dte in dates
            from row in dcx.CaseRanges
            where dte >= row.OpenDate && dte <= row.CloseDate
            group dte by dte into grp
            select new {Date=grp.Key, Count=grp.Count()};

【讨论】:

  • 这成功了!只需将其更改为 var dates = Enumerable.Range(0, 4).Select(offset =&gt; startDate.AddDays(offset));group dte by dte into grp
  • @BenC3 已修复。你需要使用.AsQueryable吗?
  • 没有它就运行。我仍然需要弄清楚如何在没有未结案件的日期上获得 0,但这应该不会太棘手。
  • @BenC3 我不太确定;它可能需要一个完全不同的查询。见here。请记住,该答案中提到了一些性能问题。
  • 我已经运行了两次脚本 - 一次以您上面概述的方式,另一次通过从数据库中获取日期范围内的所有案例作为匿名类型,只有 OpenDate 和 CloseDate,如 .Select(t=&gt;new { t.OpenDate, t.CloseDate }).ToList() ,然后对范围内的每个日期使用循环并查询内存中的匿名类型,以便只调用一次数据库。后一种方法结果明显更快,并且提供了我们需要的 0 计数,所以我们最终使用了它。
【解决方案2】:

使用 foreach 循环并将开始日期和结束日期添加到新列表中,以便新列表现在包含 6 个项目,然后在该新列表上执行 GroupBy。

【讨论】:

  • 最好显示一小段代码,以便 OP 有一个想法
猜你喜欢
  • 2021-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-05
  • 2017-07-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多