【问题标题】:How to use LINQ to group by and order by certain column如何使用 LINQ 对特定列进行分组和排序
【发布时间】:2017-11-29 14:05:12
【问题描述】:

更新:添加了一个新列,将作为字符串字段的日期和时间列组合到作为日期时间字段的 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));

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

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

注意:例如,如果 Kelly 是 John(John 出现两次),那么 Ardsley 小组将排在 Orlance 之前。

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

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 的行之后追加 Mike's 的其余行,在 Jenny 的行之后追加 Jenny's 的其余行,等等?这可以在同一个 LINQ 中完成吗?

【问题讨论】:

  • 你试过什么?请阅读:stackoverflow.com/help/how-to-ask
  • 了解 LINQ OrderBy 和 GroubBy,没有什么难的,您只需将一些 OrderBy 相互链接并按名称对结果进行分组
  • 到目前为止我已经添加了我的代码...
  • 尝试以下操作: DataTable ordered = dataTable.AsEnumerable() .OrderBy(en => en.Field("Date")) .ThenBy(en1 => en1.Field( "名称")).CopyToDataTable();
  • @jdweng 请看这个:paste.ee/p/llAc6

标签: c# linq datatable


【解决方案1】:

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

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

【讨论】:

  • 我已更新我的问题以更好地阐明我的要求。顺便说一句,感谢您的反馈。
  • 你怎么得到en.en.Name但我只得到en.Field&lt;&gt;
  • 开始时我没有使用DataTable
  • @si8 根据您改进的问题更新了我的答案。
  • 谢谢。我会测试一下,让你知道结果如何。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-30
  • 2021-01-20
  • 1970-01-01
  • 2018-02-27
  • 1970-01-01
  • 2016-06-28
  • 1970-01-01
相关资源
最近更新 更多