GroupBy来自Datetime变量的日期

时间:2014-04-21 08:29:33

标签: .net vb.net linq linqpad

我有这种格式的数据库:

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用户,我想要求帮助。

1 个答案:

答案 0 :(得分:3)

GroupBy extension method返回一个IEnumerable(IGrouping(Of TKey,TSource),每个IGrouping代表一个项集合并公开Key属性,在这种情况下将是日期您可以应用选择来投影分组并将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