Linq -按日期分组并选择计数

cld4siwp  于 2022-12-30  发布在  其他
关注(0)|答案(6)|浏览(160)

我目前正在解决一个问题,我想运行一个查询,按所选日期对结果进行分组。
在这个例子中,假设一个简单的模型如下:

public class User
{
      public DateTime LastLogIn {get; set;}
      public string Name {get; set;}
}

我寻找的解决方案是按日期获取登录用户的计数。在数据库中,DateTime与日期和时间组件一起存储,但对于此查询,我实际上只关心日期。
我现在拥有的是:

context.Users
            .Where((x.LastLogIn  >= lastWeek)    
                && (x.LastLogIn <= DateTime.Now))
            .GroupBy(x => EntityFunctions.TruncateTime(x.LastLogIn))
            .Select(x => new
            {
                Value = x.Count(),
                Day = (DateTime)EntityFunctions.TruncateTime(x.Key)
            }).ToList();

但是上面的代码返回一个空列表。
最终目标是拥有一个对象列表,其中包含一个Value(某一天登录的用户数)和一个Day(所讨论的日期)
有什么想法吗?
将查询更改为:

context.Users
            .Where((x.LastLogIn  >= lastWeek)    
                && (x.LastLogIn <= DateTime.Now))
            .GroupBy(x => EntityFunctions.TruncateTime(x.LastLogIn))
            .Select(x => new
            {
                Value = x.Count(),
                Day = (DateTime)x.Key
            }).ToList();

它现在返回一个列表,其中只有一个条目,Value是匹配where子句的用户总数,Day是第一天。

    • 注意:**证明上面的代码是正确的,我只是做错了别的事情。

它正在生成的sql是(注意这里可能有非常轻微的语法错误,我在示例中调整了它):

SELECT 
1 AS [C1], 
[GroupBy1].[A1] AS [C2], 
 CAST( [GroupBy1].[K1] AS datetime2) AS [C3]
FROM ( SELECT 
        [Filter1].[K1] AS [K1], 
        COUNT([Filter1].[A1]) AS [A1]
        FROM ( SELECT 
                 convert (datetime2, convert(varchar(255), [Extent1].[LastLogIn], 102) ,  102) AS [K1], 
                1 AS [A1]
                FROM [dbo].[Users] AS [Extent1]
                WHERE (([Extent1].[LastLogIn] >= @p__linq__1) AND ([Extent1].[LastLogIn] <= @p__linq__2)
        )  AS [Filter1]
       GROUP BY [K1]
)  AS [GroupBy1]
eqfvzcg8

eqfvzcg81#

此处不需要第二个TruncateTime

context.Users
    .Where((x.LastLogIn  >= lastWeek) && (x.LastLogIn <= DateTime.Now))
    .GroupBy(x => DbFunctions.TruncateTime(x.LastLogIn))
    .Select(x => new
    {
        Value = x.Count(),
        // Replace the commented line
        //Day = (DateTime)DbFunctions.TruncateTime(x.Key)
        // ...with this line
        Day = (DateTime)x.Key
    }).ToList();

GroupBy已经截断了DateTime的时间,因此您不需要再次调用它。
要使用DbFunctions.TruncateTime,您需要引用程序集System.Data.Entity并包含using System.Data.Entity;

**注:**已编辑以解决EntityFunctions的弃用问题。

monwx1rj

monwx1rj2#

试试这个:

.GroupBy(x => new {Year = x.LastLogIn.Year, Month = x.LastLogIn.Month, Day = x.LastLogIn.Day)
                .Select(x => new
                {
                    Value = x.Count(),
                    Year = x.Key.Year,
                    Month = x.Key.Month,
                    Day = x.Key.Day
                })
gopyfrb3

gopyfrb33#

你可以很容易地做到这一点:

yourDateList.GroupBy(i => i.ToString("yyyyMMdd"))
             .Select(i => new
             {
                 Date = DateTime.ParseExact(i.Key, "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None),
                 Count = i.Count()
             });
xggvc2p6

xggvc2p64#

我遇到了这个相同的问题,以获得一个基于组的计数由一个日期时间列。这是我所做的。感谢这里的一些答案。我尝试了最小版本,我用这个代码在。netcore解决方案。

var result = _context.yourdbmodel
              .GroupBy(x=>x.yourdatetimecolumn.Value.Date)
              .select(x=> new 
              {
                Count = x.Count(),
                Date = (DateTime)x.Key // or x.Key.Date (excluding time info) or x.Key.Date.ToString() (give only Date in string format) 
              })
              .ToList();

输出示例:
[{"请求日期":"2020年4月1日","请求计数":3},{"请求日期":"2020年4月7日","请求计数":第十四条]
希望这对以后的人有帮助。

xienkqul

xienkqul5#

您也可以在一行中完成。

var b = (from a in ctx.Candidates select a)
            .GroupBy(x => x.CreatedTimestamp.Date).Select(g => new { Date=(g.Key).ToShortDateString(), Count = g.Count() });
0aydgbwb

0aydgbwb6#

只需借助ToList()将第一个IQueryable转换为IEnumerable(List),然后使用groupby

context.Users
            .Where((x.LastLogIn  >= lastWeek) && (x.LastLogIn <= DateTime.Now))
            .ToList()
            .GroupBy(x => x.LastLogIn.Date))
            .Select(x => new
            {
                Value = x.Count(),
                Day = (DateTime)x.Key
            }).ToList();

相关问题