【问题标题】:How to group a list and display a inner list in a datatable by linq如何通过linq对列表进行分组并在数据表中显示内部列表
【发布时间】:2018-12-03 07:54:27
【问题描述】:

您好,我有一个如下列表

var data2 = dt.AsEnumerable().Select(x => new
            {
                SubTask = x.Field<string>("subtask"),
                Name = x.Field<string>("FirstName"),
                Date = x.Field<string>("Day") + ", " + x.Field<string>("Date"),
                Hour = System.Text.Encoding.UTF8.GetString(x.Field<System.Byte[]>("EmpHours"))
            });

我的列表如下所示

Name   Date           Hour        Subtask
----    ------      -------      ----------
a      2018-11-01       1            task1
a      2018-11-01       2           task2
b      2018-11-01      'PTO'        'PTO'
c       2018-11-01      5            design
c       2018-11-01      3            coding

我想按日期和名称分组,并将结果显示在主列表内的内部列表中。

我想按日期和名称分组,然后对每个名称的小时列求和。 小时列是字符串类型'它可能包含字符串'PTO'或像'2'这样的数字。

我试过下面的查询

var data2 = dt.AsEnumerable().Select(x => new
            {
                SubTask = x.Field<string>("subtask"),
                Name = x.Field<string>("FirstName"),
                Date = x.Field<string>("Day") + ", " + x.Field<string>("Date"),
                Hour = System.Text.Encoding.UTF8.GetString(x.Field<System.Byte[]>("EmpHours")),
                EmpList=  (from grp in dt.AsEnumerable()
                           .GroupBy(row => new {
                               Name = row.Field<string>("Name"), 
                               Date = row.Field<string>("Date") 
                           }).Select(g => new { Date = g.Key.Date, Name = g.Key.Name, Hour = g.Sum(i => i.Field<decimal>("Hour"));

            })

 I want output like below table 




  Name   Date           Hour        Subtask
    ----    ------      -------      ----------
    a      2018-11-01      3           task1.task2    
    b      2018-11-01      'PTO'       'PTO'
    c       2018-11-01      8          design,coding

谁能帮我解决这个问题?

【问题讨论】:

  • 您遇到的具体问题是什么?你现在得到什么?你有什么期待?
  • 那么当Hour 包含“PTO”时,你想怎么总结呢?忽略它(即视为零)?您的第二个示例还引用了一个字段 Name,但您的第一个示例没有它 - 它的 FirstName
  • @Jamiec ,如果是PTO,在小时栏中显示为'PTO',无需求和。
  • @sandeep.mishra 我认为你没有抓住重点 - string "PTO" 与 Sum 的结果的数值完全不兼容
  • 我已经修改了我的问题。请立即查看,如果您清楚,请告诉我

标签: c# linq datatable


【解决方案1】:

基本上,您要执行的操作将要求您知道Hour 是否为数字并对其进行分组。以下内容似乎可以满足您的需求

 var result = data.GroupBy(x => new { 
                   x.Name,                                  // Group on Name
                   x.Date,                                  // And date
                   IsHourNumeric=x.Hour.All(Char.IsNumber)  // And whether Hour is numeric
             })
            .Select(g => new {
              Name = g.Key.Name,
              Date = g.Key.Date,
              Hour = g.Key.IsHourNumeric 
                       ? g.Select(x => int.Parse(x.Hour)).Sum().ToString() // If hour was numeric sum
                       : g.First().Hour, // Otherwise just take the first item ?!?
              SubTasks = g.Select(x => x.SubTask)
            });

您的数据的实时示例在这里:https://rextester.com/DPJZUH68065

【讨论】:

    【解决方案2】:

    在您的初始结果后应用 linq group by(添加 .TOList())

    var data2 = dt.AsEnumerable().Select(x => new
            {
                SubTask = x.Field<string>("subtask"),
                Name = x.Field<string>("FirstName"),
                Date = x.Field<string>("Day") + ", " + x.Field<string>("Date"),
                Hour = System.Text.Encoding.UTF8.GetString(x.Field<System.Byte[]>("EmpHours"))
            }).ToList();
    

    现在将 group by 应用于此结果,如下例所示:

    var result = data2.GroupBy(n => new { n.Name, n.Date})
            .Select(cl => new Result
            {
                Name = cl.First().Name,
                Date = cl.First().Date,
                Hours = cl.Sum(c => c.Hour),
            }).ToList();
    

    【讨论】:

    • 但 Hour 列是字符串,可能包含值 'PTO'
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-05
    • 2021-02-11
    • 1970-01-01
    • 1970-01-01
    • 2015-04-07
    相关资源
    最近更新 更多