【问题标题】:GroupBy Date from Datetime variable来自 Datetime 变量的 GroupBy 日期
【发布时间】:2014-04-21 08:29:33
【问题描述】:

我有一个这种格式的数据库:

Datetime             | Air Temperature
---------------------+-----------------
...                  |
01.12.2013 00:00:00  | 2
01.12.2013 01:00:00  | 2
01.12.2013 02:00:00  | 2
01.12.2013 03:00:00  | 1.7
01.12.2013 04:00:00  | 2
01.12.2013 05:00:00  | 2
01.12.2013 06:00:00  | 2.2
...

并尝试使用 VB.Net 中的 linq 对日期范围内每一天的结果进行分组:

Dim query = (From i In db _
    Where i.Datetime > #12/1/2013 00:00# AndAlso i.Datetime < #1/1/2014 00:00# _
    Select i).GroupBy(Function(f) f.Datetime.Day)

Console.WriteLine(query)

但查询输出是按数据库中的每个项目(每小时)而不是按天分组的:

[
  {
    "Key": 1,
    "Values": [
      {
        "Datetime": "2013-12-01T00:00:00",
        "AirTemperature": 2.0,
      }
    ]
  },
  {
    "Key": 1,
    "Values": [
      {
        "Datetime": "2013-12-01T01:00:00",
        "AirTemperature": 2.0,
      }
    ]
  },
...

首先我使用i.DateTime.Date 作为分组运算符,但由于它没有按我想要的方式工作,我认为将 Datetime 对象转换为短日期字符串可以让我到达那里。它并没有改变任何事情,作为新的 linq 用户,我想寻求帮助。

【问题讨论】:

  • 您是否需要每天单一的总温度(例如平均值),如果是这样,在 GroupBy 之后您可以使用类似 Select(Function(key,values) values.Average(Function(v) v.t) )
  • 是的,这就是我想要的 - 每天提取最高和最低温度,所以我需要分组......但仍然无法到达那里

标签: .net vb.net linq linqpad


【解决方案1】:

GroupBy extension method 返回一个 IEnumerable(Of IGrouping(Of TKey,TSource),每个 IGrouping 代表一个项目集合并公开一个 Key 属性,在这种情况下将是日期。您可以应用 Select投影分组并将 Min 和 Max 聚合应用于项目,例如(注意:由于我没有数据库,因此我为查询结果设置了一些示例数据):

Structure Item
    Public DateTime As DateTime
    Public Temp As Double
End Structure

Sub Main()
    ' Test data
    Dim query = {
        New Item With {.DateTime = #12/1/2013 00:00#, .Temp = 2},
        New Item With {.DateTime = #12/1/2013 01:00#, .Temp = 2},
        New Item With {.DateTime = #12/1/2013 02:00#, .Temp = 2},
        New Item With {.DateTime = #12/1/2013 03:00#, .Temp = 1.7},
        New Item With {.DateTime = #12/1/2013 04:00#, .Temp = 2},
        New Item With {.DateTime = #12/1/2013 05:00#, .Temp = 2},
        New Item With {.DateTime = #12/1/2013 06:00#, .Temp = 2.2}
    }

    ' Aggregate with extension methods
    Dim aggregated =
        query.GroupBy(Function(item) item.DateTime.Date) _
             .Select(Function(grouping) _
                     New With {
                        .DateTime = grouping.Key,
                        .Max = grouping.Max(Function(item) item.Temp),
                        .Min = grouping.Min(Function(item) item.Temp)
                        })

    ' Aggregate with sugared LINQ
    Dim aggregated2 =
        From item In query
        Group item By key = item.DateTime.Date Into Group
        Select New With {
            .DateTime = key,
            .Min = Group.Min(Function(item) item.Temp),
            .Max = Group.Max(Function(item) item.Temp)}

    ' Show aggregated results
    For Each item In aggregated2
        Console.WriteLine(item.DateTime & " " & item.Min & " " & item.Max)
    Next
End Sub

如需参考,请查看LINQ Query Samples - Grouping Operators

【讨论】:

  • 感谢您的解释和回答。您的示例按照它所说的进行,它帮助我看到我上面的查询在您的示例数据上也按预期工作。但不是我使用的数据库,所以我假设我在代码和来自 LinqPad 的 Access 数据库之间存在一些管道问题。
  • 确实,假设问题似乎出在MSAccessDataContextDriver.lpx LinqPad 驱动程序上。将 Access 数据库迁移到 SQL 服务器后,分组按预期工作。
猜你喜欢
  • 2010-11-10
  • 1970-01-01
  • 2013-09-08
  • 1970-01-01
  • 2017-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多