如何通过linq在数据表中对列表进行分组并显示内部列表

时间:2018-12-03 07:54:28

标签: c# linq datatable

嗨,我有一个如下列表

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

有人可以帮我吗?

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

在初始结果之后添加linq group by(添加了.TOList())

SELECT ENROLL.Mno, SUM(CASE
    WHEN Grade = 'A' THEN 4.0
    WHEN Grade = 'B' THEN 3.0
    WHEN Grade = 'C' THEN 2.0
    WHEN Grade = 'D' THEN 1.0
    WHEN Grade = 'F' THEN 0.0
END * COURSE.Credit) / SUM(COURSE.Credit)
FROM ENROLL
INNER JOIN SECTION ON ENROLL.Sid = Section.Sid
INNER JOIN COURSE ON SECTION.Cno = COURSE.Cno
GROUP BY ENROLL.Mno

现在将分组依据应用于此结果,如下例所示:

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