【问题标题】:Format date with leading zeros in EF Core Linq GroupBy statement在 EF Core Linq GroupBy 语句中使用前导零格式化日期
【发布时间】:2020-05-15 08:28:17
【问题描述】:

我有一个 LINQ 语句 (EF Core 3.1),我想按时间戳列的年份和月份进行分组,例如“2020-03”。

var result = _context.Messages
            .Where(x => x.timestamp != null)
            .GroupBy(x => x.timestamp.Value.Year.ToString()+"-" + x.timestamp.Value.Month.ToString())
            .Select(x => new { date = x.Key, count = x.Count() })

问题是日期的结果格式是“2020-3”,导致后面的排序问题。

如何将月份字符串格式化为始终包含前导零的 2 位数字?

我阅读了很多关于 SqlFunctions 的内容 - 但这些在 EF Core 中不可用。还有其他方法吗?

【问题讨论】:

  • 您应该按实际字段分组,然后在以后处理格式或作为添加的属性
  • 从 sql 的角度来看,不做 group by 中的数据转换可能会有所帮助。 Sql 将能够使用那些列上的索引。然后,您可以将它们放入内存并进行格式化。只看结果。每个不同组一种格式与每行一种格式。并使用索引而不是对新创建的键进行分组。

标签: c# linq linq-to-sql ef-core-3.1


【解决方案1】:

您可以按实际的年/月分组,然后将这些值投影出来。这样,分组完全在 SQL 中完成。拥有内存中的集合后,您可以再次投影创建排序键以及 D2 format specifer

var result = _context.Messages
            .Where(x => x.timestamp != null)
            .GroupBy(x => new { 
                x.timestamp.Value.Year,
                x.timestamp.Value.Month
             })
            .Select(x => new { 
                Year = x.Key.Year, 
                Month = x.Key.Month, 
                Count = x.Count() 
             })
            .AsEnumerable()
            .Select(x => new {
                Date = $"{x.Year:D2}-{x.Month:D2}",
                Count = x.Count
             }) 
            .ToList();

【讨论】:

  • 完美的想法,在服务器上排在第一位,然后在第二次选择中进行字符串形成:-) 工作!
【解决方案2】:

您可以使用值为“d2”的ToString() 方法的格式重载。这样,格式将确保您始终获得两位数:

x.timestamp.Value.Month.ToString("d2")

【讨论】:

  • 这也是我的想法之一 - 但它失败并引发运行时错误,即无法将 LINQ 表达式转换为 SQL 语句。
猜你喜欢
  • 2021-10-13
  • 1970-01-01
  • 2018-02-08
  • 1970-01-01
  • 2011-10-07
  • 1970-01-01
  • 1970-01-01
  • 2015-06-06
  • 2014-10-12
相关资源
最近更新 更多