Используйте LINQ для группировки данных из таблицы данных

#vb.net #linq #grouping

#vb.net #linq #группировка

Вопрос:

У меня вопрос по linq. Я хочу использовать LINQ для группировки данных из таблицы данных (столбцы: RUN_NAME, H_YYYY,H_MM, H_MON).

Данные выглядят следующим образом:

RUN_NAME H_YYYY H_MM H_MON
2019-1 2019 1 Янв.
2019-1 2019 2 Февраль
2019-1 2019 3 Мар
2019-1 2019 4 Апрель
2019-2 2019 5 Может
2019-2 2019 6 Июнь
2019-2 2019 7 Июль
2019-2 2019 8 Август
2019-3 2019 9 Сентябрь
2019-3 2019 10 Октябрь
2019-3 2019 11 Ноябрь
2019-3 2019 12 Дек

Мне нужно что-то подобное в результате, когда отдельные детали запуска группируются как часть каждого запуска (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()

 

где мое определение календарного месяца выглядит следующим образом:

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

и мое определение класса MonthScope выглядит следующим образом:

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

Комментарии:

1. Так в чем же проблема? Какой результат дает ваш код и чем он отличается от ваших ожиданий?

2. Вы действительно хотите сгруппировать или просто пытаетесь отсортировать? Я не вижу никаких признаков каких-либо попыток группировки в вашем коде, поэтому, очевидно, группировка не произойдет. Если вы действительно хотите сгруппировать, вам следует прочитать о том, как группировать с помощью LINQ, а затем попытаться реализовать то, что вы узнали, а затем задать вопрос об этом, если это не сработает.

3. Здесь приведен пример группировки, который поможет вам начать. Это было на полпути вниз по первой странице результатов поиска «vb.net linq group».

Ответ №1:

Итак, я считаю, что ваше «мне нужно что-то подобное» — это представление объектов, которые вы хотите; 3 CalendarMonth каждый с заполненным списком Month_Scope, которые являются MonthScopes (их 4)

Во-первых, я бы очень хотел немного подправить ваши классы, во-первых, убрать сомнительные имена свойств, а во-вторых, добавить пару конструкторов, которые будут создавать класс из потока данных. Вы можете структурировать это каким-либо другим способом, если хотите (например, общий метод FromDataRow или factory), или вы можете объединить эту логику обратно в свой оператор 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 of , который намного приятнее:

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

Комментарии:

1. Отлично ! Это именно то, что я искал. Спасибо. Очень признателен. Новичок в LINQ здесь.