如何使用 LINQ 对特定列进行分组和排序

Si8*_*Si8 0 c# linq datatable

更新:添加了一个新列,将日期和时间列(字符串字段)合并到 DateTimeCombined 列(日期时间字段)中

因此,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));
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

第一个 LINQ 函数应该是获取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
Run Code Online (Sandbox Code Playgroud)

下一个功能应该是通过以下方式订购DateTimeCombined

- 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
Run Code Online (Sandbox Code Playgroud)

下一个函数应该是为每个名称放置其余行(最终的 DataTable 应如下所示):

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
Run Code Online (Sandbox Code Playgroud)

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

到目前为止我尝试过的:

var ordered = dataTable.AsEnumerable().OrderBy(en => en.Field<DateTime>("DateTimeCombined")).CopyToDataTable();
Run Code Online (Sandbox Code Playgroud)

更新:

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

只给我名字。

更新:

  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();
Run Code Online (Sandbox Code Playgroud)

以上按预期工作:

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
Run Code Online (Sandbox Code Playgroud)

但前提是我取每组的第一行(按名称)。如果我按组获取所有内容,则行会全部混淆。现在我怎样才能在迈克的行之后追加其余的Mike's行,在珍妮的行之后追加其余的Jenny's行,依此类推?这可以在同一个 LINQ 中完成吗?

Net*_*age 5

根据新编辑的问题,我有这个:

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();
Run Code Online (Sandbox Code Playgroud)