代码之家  ›  专栏  ›  技术社区  ›  Si8

如何使用LINQ按特定列分组和排序

  •  0
  • Si8  · 技术社区  · 7 年前

    已更新 :添加了一个新列,将作为字符串字段的日期和时间列组合到作为日期时间字段的日期时间组合列中

    所以LINQ应该做的是按名称列分组,并获得每个名称的行,该名称具有最早的日期+时间。然后,它应该为名称添加行的其余部分。

    dataT = new DataTable();
    dataT.Columns.Add("Date", typeof(string));
    dataT.Columns.Add("Time", typeof(string));
    dataT.Columns.Add("Day", typeof(string));
    dataT.Columns.Add("Name", typeof(string));
    dataT.Columns.Add("Place", typeof(string));
    dataT.Columns.Add("DateTimeCombined", typeof(DateTime));
    dataT.Columns.Add("NameMessage", typeof(string));
    

    下面是起始数据表(默认情况下检索):

    Date        Time        Day     Name        Place       DateTimeCombined            NameMessage
    6/29/2017   8:30AM      MON     John        Orlance     6/29/2017 8:30:00 AM
    6/29/2017   8:40AM      MON     John        Orlance     6/29/2017 8:40:00 AM
    6/29/2017   8:50AM      MON     John        Orlance     6/29/2017 8:50:00 AM        
    6/29/2017   9:10AM      MON     John        Orlance     6/29/2017 9:10:00 AM
    6/29/2017   9:20AM      MON     John        Orlance     6/29/2017 9:20:00 AM
    6/29/2017   1:00PM      MON     John        Orlance     6/29/2017 1:00:00 PM
    6/30/2017   8:30AM      TUE     John        Orlance     6/30/2017 8:30:00 AM
    6/30/2017   8:40AM      TUE     John        Orlance     6/30/2017 8:40:00 AM
    6/29/2017   8:15AM      MON     Mike        Atlanta     6/29/2017 8:15:00 AM
    6/29/2017   8:30AM      MON     Mike        Atlanta     6/29/2017 8:30:00 AM
    6/29/2017   8:40AM      MON     Mike        Atlanta     6/29/2017 8:40:00 AM
    6/29/2017   9:10AM      MON     Mike        Atlanta     6/29/2017 9:10:00 AM
    6/29/2017   9:20AM      MON     Mike        Atlanta     6/29/2017 9:20:00 AM
    6/30/2017   8:30AM      TUE     Mike        Atlanta     6/30/2017 8:30:00 AM
    6/30/2017   8:40AM      TUE     Mike        Atlanta     6/30/2017 8:40:00 AM
                                    Christine   Marion                                  None
                                    Steph       Kearney                                 None
    6/29/2017   8:30AM      MON     Jenny       Boise       6/29/2017 8:30:00 AM
    6/29/2017   8:40AM      MON     Jenny       Boise       6/29/2017 8:40:00 AM
    6/29/2017   8:50AM      MON     Jenny       Boise       6/29/2017 8:50:00 AM
    6/29/2017   9:10AM      MON     Jenny       Boise       6/29/2017 9:10:00 AM
    6/29/2017   9:20AM      MON     Jenny       Boise       6/29/2017 9:20:00 AM
    6/30/2017   8:30AM      TUE     Jenny       Boise       6/30/2017 8:30:00 AM
    6/30/2017   8:40AM      TUE     Jenny       Boise       6/30/2017 8:40:00 AM
    6/29/2017   8:30AM      MON     Kelly       Ardsley     6/29/2017 8:30:00 AM
    6/29/2017   8:40AM      MON     Kelly       Ardsley     6/29/2017 8:40:00 AM
    6/29/2017   8:50AM      MON     Kelly       Ardsley     6/29/2017 8:50:00 AM
    6/29/2017   9:10AM      MON     Kelly       Ardsley     6/29/2017 9:10:00 AM
    6/29/2017   9:20AM      MON     Kelly       Ardsley     6/29/2017 9:20:00 AM
    6/30/2017   8:30AM      TUE     Kelly       Ardsley     6/30/2017 8:30:00 AM
    6/30/2017   8:40AM      TUE     Kelly       Ardsley     6/30/2017 8:40:00 AM
                                    Joseph      Houston                                 None
    

    DateTimeCombined

    6/29/2017   8:30AM      MON     John        Orlance     6/29/2017 8:30:00 AM
    6/29/2017   8:15AM      MON     Mike        Atlanta     6/29/2017 8:15:00 AM
    6/29/2017   8:30AM      MON     Jenny       Boise       6/29/2017 8:30:00 AM
    6/29/2017   8:30AM      MON     Kelly       Ardsley     6/29/2017 8:30:00 AM
    

    下一个函数应该是通过 日期时间组合 :

    - If `DateTimeCombined` is same, order first by `DateTimeCombined` and then by Name.
    
    - If `DateTimeCombined` is same AND Name is same, order first by `DateTimeCombined` and then by Name and then by Place.
    
    
    6/29/2017   8:15AM      MON     Mike        Atlanta     6/29/2017 8:15:00 AM
    6/29/2017   8:30AM      MON     Jenny       Boise       6/29/2017 8:30:00 AM
    6/29/2017   8:30AM      MON     John        Orlance     6/29/2017 8:30:00 AM
    6/29/2017   8:30AM      MON     Kelly       Ardsley     6/29/2017 8:30:00 AM
    

    6/29/2017   8:15AM      MON     Mike        Atlanta     6/29/2017 8:15:00 AM
    6/29/2017   8:30AM      MON     Mike        Atlanta     6/29/2017 8:30:00 AM
    6/29/2017   8:40AM      MON     Mike        Atlanta     6/29/2017 8:40:00 AM
    6/29/2017   9:10AM      MON     Mike        Atlanta     6/29/2017 9:10:00 AM
    6/29/2017   9:20AM      MON     Mike        Atlanta     6/29/2017 9:20:00 AM
    6/30/2017   8:30AM      TUE     Mike        Atlanta     6/30/2017 8:30:00 AM
    6/30/2017   8:40AM      TUE     Mike        Atlanta     6/30/2017 8:40:00 AM
    6/29/2017   8:30AM      MON     Jenny       Boise       6/29/2017 8:30:00 AM
    6/29/2017   8:40AM      MON     Jenny       Boise       6/29/2017 8:40:00 AM
    6/29/2017   8:50AM      MON     Jenny       Boise       6/29/2017 8:50:00 AM
    6/29/2017   9:10AM      MON     Jenny       Boise       6/29/2017 9:10:00 AM
    6/29/2017   9:20AM      MON     Jenny       Boise       6/29/2017 9:20:00 AM
    6/30/2017   8:30AM      TUE     Jenny       Boise       6/30/2017 8:30:00 AM
    6/30/2017   8:40AM      TUE     Jenny       Boise       6/30/2017 8:40:00 AM
    6/29/2017   8:30AM      MON     John        Orlance     6/29/2017 8:30:00 AM
    6/29/2017   8:40AM      MON     John        Orlance     6/29/2017 8:40:00 AM
    6/29/2017   8:50AM      MON     John        Orlance     6/29/2017 8:50:00 AM        
    6/29/2017   9:10AM      MON     John        Orlance     6/29/2017 9:10:00 AM
    6/29/2017   9:20AM      MON     John        Orlance     6/29/2017 9:20:00 AM
    6/29/2017   1:00PM      MON     John        Orlance     6/29/2017 1:00:00 PM
    6/30/2017   8:30AM      TUE     John        Orlance     6/30/2017 8:30:00 AM
    6/30/2017   8:40AM      TUE     John        Orlance     6/30/2017 8:40:00 AM
    6/29/2017   8:30AM      MON     Kelly       Ardsley     6/29/2017 8:30:00 AM
    6/29/2017   8:40AM      MON     Kelly       Ardsley     6/29/2017 8:40:00 AM
    6/29/2017   8:50AM      MON     Kelly       Ardsley     6/29/2017 8:50:00 AM
    6/29/2017   9:10AM      MON     Kelly       Ardsley     6/29/2017 9:10:00 AM
    6/29/2017   9:20AM      MON     Kelly       Ardsley     6/29/2017 9:20:00 AM
    6/30/2017   8:30AM      TUE     Kelly       Ardsley     6/30/2017 8:30:00 AM
    6/30/2017   8:40AM      TUE     Kelly       Ardsley     6/30/2017 8:40:00 AM
    

    注:例如,如果凯利是约翰(约翰出现两次),那么阿德斯利小组将排在奥尔兰斯之前。

    到目前为止,我尝试了:

    var ordered = dataTable.AsEnumerable().OrderBy(en => en.Field<DateTime>("DateTimeCombined")).CopyToDataTable();
    

    更新:

    var ordered = dataTable.AsEnumerable()
                    .OrderBy(en => en.Field<DateTime>("DateTimeCombined"))
                .GroupBy(en1 => en1.Field<string>("Name")).ToList();
    

      var q = dataTable.AsEnumerable()
                    .GroupBy(item => item.Field<string>("Name"))
                    .SelectMany(grouping => grouping.Take(1))
                    .OrderBy(item => item.Field<DateTime>("CombinedDateTime"))
                    .ThenBy(item => item.Field<string>("Name"))
                    .ThenBy(item => item.Field<string>("Place"))
                    .CopyToDataTable();
    

    以上工作如预期:

    6/29/2017   8:15AM      MON     Mike        Atlanta     6/29/2017 8:15:00 AM
    6/29/2017   8:30AM      MON     Jenny       Boise       6/29/2017 8:30:00 AM
    6/29/2017   8:30AM      MON     John        Orlance     6/29/2017 8:30:00 AM
    6/29/2017   8:30AM      MON     Kelly       Ardsley     6/29/2017 8:30:00 AM
    

    Mike's 在Mike的行之后,附加其余的 Jenny's

    1 回复  |  直到 7 年前
        1
  •  4
  •   NetMage    6 年前

    var ordered = dataT.AsEnumerable()
                       .GroupBy(en => new { Name = en.Field<string>("Name"), Place = en.Field<string>("Place") })
                       .OrderBy(eng => eng.Min(en => en.Field<DateTime>("DateTimeCombined")))
                       .ThenBy(eng => eng.Key.Name).ThenBy(eng => eng.Key.Place)
                       .SelectMany(eng => eng.OrderBy(en => en.Field<DateTime>("DateTimeCombined")), (eng, en) => en)
                       .CopyToDataTable();