繁体   English   中英

如何根据日期(天)c# 按数据库中的记录分组?

[英]How to group by records from database based on date (day) c#?

我知道这可能是一个可能重复的问题,如果是,请原谅我。

有没有办法按日期对数据库中的所有记录进行GroupBy

所以:

  • 假设我在 22/05/2022 这个日期有多个记录
  • 并说我从这个日期开始有多条记录:23/05/2022

我可以根据日期参数 22/05 和 23/05 对所有记录进行分组吗?

这样我最终会得到一个包含每天n列表的列表。

这是我所做的:

var grpQuery = await ctx.Registration.GroupBy(c => c.DateReference.Day).ToListAsync();

在哪里:

  • Registration是我从中提取数据的表格
  • DateReference是包含日期的Date object

但我收到此错误“无法翻译 linq 表达式”。

有人可以给我一些建议吗?

编辑

我试过了,但似乎没有加载任何数据,即使设置断点也不会返回任何内容:

                var grpQuery = await query.GroupBy(d => new { DateReference = d.DateReference.Date }).Select(c => new RegistrationViewModel()
 {
   RegistrationId = c.FirstOrDefault().RegistrationId,
   PeopleId = c.FirstOrDefault().PeopleId,
   DateReference = c.Key.DateReference,
   DateChange = c.FirstOrDefault().DateChange,
   UserRef = c.FirstOrDefault().UserRef,
   CommissionId = c.FirstOrDefault().CommissionId,
   ActivityId = c.FirstOrDefault().ActivityId,
   MinuteWorked = c.FirstOrDefault().MinuteWorked,
 }).OrderBy(d => d.DateReference).ToListAsync();

在哪里:

  • RegistrationViewModel包含所有这些属性,包括DateReference
  • 如果我使用 API 调用该方法,则卡在“待处理”

首先,不要。 即使查询是固定的,数据库中的等效查询也是 GROUP BY DATEPART(day,registration.Date) 不能使用索引,因此速度很慢。

根据文档,相当于DATEPART(day, @dateTime)dateTime.Day 不过,查询仍然需要有一个正确的Select

正确的查询是:

counts = ctx.Registrations.GroupBy(r=>r.RegistrationDate.Day)
                 .Select(g=>new {Day=g.Key,Count=g.Count())
                 .ToList();

等效的慢查询将是

SELECT DATEPART(day,registration.Date) as Day,count(*)
FROM Registrations
GROUP BY DATEPART(day,registration.Date)

如果我们不得不按日期过滤,情况会变得更糟。 该查询必须扫描整个表,因为它不能使用任何覆盖Date列的索引

SELECT DATEPART(day,registration.Date) as Day,count(*)
FROM Registrations
WHERE Date >'20220901'
GROUP BY DATEPART(day,registration.Date)

想象一下,必须扫描 10 年的注册才能获得当前月份。

这是一个报告查询。 对于与日期相关的报告,使用预先填充的日历表可以使查询变得更加容易。

SELECT Calendar.Day,COUNT(*)
FROM Registrations r
INNER JOIN Calendar on r.RegistrationDate=Calendar.Date
GROUP BY Calendar.Day

或者

SELECT Calendar.Year, Calendar.Semester, Calendar.Day,COUNT(*)
FROM Registrations r
INNER JOIN Calendar on r.RegistrationDate=Calendar.Date
WHERE Calendar.Year = @someYear
GROUP BY Calendar.Year, Calendar.Semester,Calendar.Day

日历表或日期维度是一个表,其中包含预填充的日期、年、月、学期或任何其他报告期以及它们的名称或使报告更容易所需的任何内容。 这样的表可以包含例如 10 年或 20 年的数据,而不会占用大量空间。 为了加快查询速度,可以在不占用太多额外空间的情况下对列进行积极索引。

在 EF Core 中执行相同操作需要将Calendar映射为实体并在 LINQ 中执行 JOIN。 这是在实体之间添加关系没有意义的情况之一:

var query=from registration in ctx.Registrations
          join date in Calendar 
              on registration.Date equals Calendar.Date
          group registration by date.Day into g
          select new { Day=g.Key, Count=g.Count()};
var counts = query.ToList();

如果您使用的是 EF Core,请尝试以下操作:

var grpQuery = await ctx.Registration.Select(a=>new {Re = a, G = (EF.Functions.DateDiffDay(a.End,DateTime.Today))}).ToListAsync().ContinueWith(d=>d.Result.GroupBy(a=>a.G));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM