使用 LINQ 中的数据透视表。

8
我有以下动态列表。
Crew   NameSurname  Period  Result
ABC    John DOE     Q1      54,09
ABC    John DOE     Q2      59,57
ABC    John DOE     Q3      62,11

我该如何在linq中获得这个结果。
Crew   NameSurname  Q1      Q2      Q3
ABC    John DOE     47,51   47,51   51,46

我尝试了这种方法,但没有得到结果。

List.GroupBy(c => c.PersonnelID)
     .Select(g => new
     {
         PersonnelID = g.Key,
         Period1 = g.Where(c => c.Period == 1).Sum(c => c.Result),
         Period2 = g.Where(c => c.Period == 2).Sum(c => c.Result),
         Period3 = g.Where(c => c.Period == 3).Sum(c => c.Result)
     });

L2S是一种ORM(类似于),而不是SQL的替代品。如果您想执行复杂的SQL转换,例如PIVOT,编写SQL语句并使用ORM将结果映射到对象要容易得多且性能更好。 - Panagiotis Kanavos
类似的SO问题 https://dev59.com/F3NA5IYBdhLWcg3wcNXF?rq=1 - Amitd
1个回答

5
你可以这样做:
var results = Data.GroupBy(l => new { l.Crew, l.NameSurname});
    .SelectMany( (key, g) => 
                 new 
                 { 
                     Crew = Key.Crew,
                     NameSurname = Key.NameSurname,  
                     groups = g 
                 });

var pivoted = new List<PivotedCrew>();

foreach(var item in results)
{
    pivoted.Add( 
        new PivotedCrew
        {
            Crew  = item.Crew,
            NameSurname = item.NameSurname,
            Q1 = item.groups.Where(x => x.Period == "Q1")
                     .FirstOrDefault().value,
            Q2 = item.groups.Where(x => x.Period == "Q2")
                     .FirstOrDefault().value,
            Q3 = item.groups.Where(x => x.Period == "Q3")
                     .FirstOrDefault().value
        });
}

但是您需要定义一个新的类。例如:
public class PivotedCrew
{
    public string Crew Id {get; set;}
    public string NameSurname {get; set;}
    public string Q1 {get; set;}   
    public string Q2 {get; set;}   
    public string Q3 {get; set;}   
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接