使用 LINQ 对数据 table 中的数据进行分组

Use LINQ to Group data from data table

我有一个 linq 问题。我想使用 LINQ 对数据表中的数据进行分组(列:RUN_NAME、H_YYYY、H_MM、H_MON)。

数据如下所示:

RUN_NAME H_YYYY H_MM H_MON
2019-1 2019 1 Jan
2019-1 2019 2 Feb
2019-1 2019 3 Mar
2019-1 2019 4 Apr
2019-2 2019 5 May
2019-2 2019 6 Jun
2019-2 2019 7 Jul
2019-2 2019 8 Aug
2019-3 2019 9 Sep
2019-3 2019 10 Oct
2019-3 2019 11 Nov
2019-3 2019 12 Dec

我需要这样的结果,其中个人 运行 详细信息被分组为每个 运行(2019-1、2019-2、2019-3)的一部分:

2019-1

  2019 1 Jan

  2019 2 Feb

  2019 3 Mar

  2019 4 Apr

2019-2

  2019 5 May

  2019 6 Jun

  2019 7 Jul

  2019 8 Aug

2019-3

  2019 9 Sep

  2019 10 Oct

  2019 11 Nov

  2019 12 Dec

这是我目前尝试过的方法:

    CalendarMonthList = (From rw As DataRow In dt.Rows Select New CalendarMonth With {
                                                                                  .Run_Name=CheckStringNull(rw("run_name").ToString),
.Month_Scope = (From r In dt.AsEnumerable Where r("run_name") = .Run_Name Select New MonthScope With {.h_yyyy = CheckDbNull(rw("h_yyyy")), 
.h_mm=CheckDbNull(rw("h_mm")),
.h_mon=CheckStringNull(rw("h_mon").ToString)}).Distinct.ToList()}).Distinct.ToList()

我对 CalendarMonth 的定义如下:

Public Class CalendarMonth
        Public Property Run_Name As String
        Public Property Month_Scope As List(Of MonthScope)
End Class

我对 MonthScope Class 的定义如下:

Public Class MonthScope
        Public Property h_yyyy As Integer?
        Public Property h_mm As Integer?
        Public Property h_mon As String
End Class

所以我的看法是您的“我需要这样的东西”代表了您想要的对象; 3 个 CalendarMonth,每个都有一个填充的 Month_Scope 列表,它们是 MonthScopes(其中 4 个)

首先,我真的很想稍微调整一下您的 classes,一方面 - 删除不可靠的 属性 名称,另一方面 - 添加几个构造函数来自数据行的 class。如果你愿意,你可以用其他方式构造它(例如共享 FromDataRow 方法或工厂),或者如果你愿意,你可以将这个逻辑合并回你的 LINQ 语句中。我这样做是作为构造函数,因为我觉得它保持清洁和 -指向那样:

Public Class CalendarMonth
    Public Property RunName As String
    Public Property MonthScopes As New List(Of MonthScope)

    Public Sub New(rn As String, ms As IEnumerable(Of DataRow))
        RunName = rn
        MonthScopes = ms.Select(Function(msro) New MonthScope(msro)).ToList()
    End Sub
End Class

Public Class MonthScope
    Public Property Yyyy As Integer?
    Public Property MM As Integer?
    Public Property Mon As String

    Public Sub New(ms As DataRow)
        If Not ms.IsNull("h_yyyy") Then Yyyy = CInt(ms("h_yyyy"))
        If Not ms.IsNull("h_mm") Then MM = CInt(ms("h_mm"))
        If Not ms.IsNull("h_mon") Then Mon = CStr(ms("h_mon"))
    End Sub
End Class

然后你有一个 LINQ 语句,它更好:

    Dim calendarMonthList = dt.AsEnumerable() _
        .GroupBy(Function(r) CStr(r("run_name"))) _
        .Select(Function(g) New CalendarMonth(g.Key, g)) _
        .ToList()