如何使用LINQ进行分组并按特定列排序

更新 :添加了一个新的列,将日期和时间列组合成字符串字段到DateTimeCombined列,这是一个DateTime字段

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

DataTable init:

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)); 

所以这是起始DataTable(默认检索):

 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 

第一个LINQ函数应该是为每个Name获取更早的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 

下一个函数应该是通过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 

下一个函数应该是为每个名称放置其余的行(最终的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 

注意:例如,如果凯利是约翰(约翰出现两次),那么Ardsley小组就会在Orlance之前。

到目前为止我尝试了什么:

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

更新:

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

只给我一个名字。

更新:

  var q = dataTable.AsEnumerable() .GroupBy(item => item.Field("Name")) .SelectMany(grouping => grouping.Take(1)) .OrderBy(item => item.Field("CombinedDateTime")) .ThenBy(item => item.Field("Name")) .ThenBy(item => item.Field("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行之后追上迈克的其余部分,在Jenny's行之后追加剩下的Jenny,等等? 这可以在同一个LINQ中完成吗?

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

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