2015-03-30 2 views
5

Ich habe die folgende Klassenstruktur:Pivot-Daten in zwei verschachtelten Liste <T> mit Linq

class Employee() 
{ 
    public String Name { get; set; } 
    public List<WorkDay> WorkDays { get; set; } 
} 

class WorkDay() 
{ 
    public DateTime Date { get; set; } 
    public Int Hours { get; set; } 
} 

Ist es möglich, die List<Employee> mit Linq zu schwenken, so dass ich wie dies in meinem Datagridview zur Folge habe:

  | Name | Name |...| Name  | 
Date  | Hours | Hours | | Hours  | 
Date  | Hours | Hours | | Hours  | 
Date  | Hours | Hours | | Hours  | 
Date  | Hours | Hours | | Hours  | 
...  | Hours | Hours | | Hours  | 

Es ist schwierig, weil es zwei verschachtelte Listen ist und ich nur Beispiele mit einzelner Liste fand, die ziemlich direkt sind. Is it possible to Pivot data using LINQ?

ich zu diesem Punkt gekommen, aber es ist durchaus noch nicht da:

var _result = Employees.SelectMany(x => x.WorkDays) 
         .GroupBy(x => x.Date) 
         .Select(y => new 
            { 
             DATE = y.Key, 
             NAME = y.Select(z => z.Employee.Name).ToArray() 
            }) 
         .ToList(); 

ich irgendwelche Vorschläge schätzen würde.

Antwort

1

Ich glaube, Sie brauchen diese: -

var result = employees.SelectMany(x => x.WorkDays, (employeeObj, workDays) => 
                new { employeeObj, workDays }) 
         .GroupBy(x => x.workDays.Date) 
         .Select(x => new 
          { 
           Date = x.Key, 
           NameAndHours = x.Select(z => 
            new { 
              Name = z.employeeObj.Name, 
              Hours = z.workDays.Hours 
             }) 
          }).ToList(); 

Hier ist die Working Fiddle mit einigen Beispieldaten ist.

+1

Das sieht gut aus, vielen Dank @Rahul. – mdziadowiec

1

Dieses Beispiel verwendet WPF, aber man könnte die Methode "PivotWorkingHours" für WinForms oder Webforms auch nutzen ...

Ausgang:

enter image description here

Fenster:

<Window x:Class="WpfApplication5.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
     <DataGrid Name="pivotTarget" ItemsSource="{Binding}"/> 
    </Grid> 
</Window> 

Implementierung:

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 

     List<Employee> demo = new List<Employee> 
           { 
            new Employee{Name = "Frank", WorkDays = new List<WorkDay> 
                     { 
                      new WorkDay{Date = new DateTime(2001,1,2), Hours = 8}, 
                      new WorkDay{Date = new DateTime(2001,1,3), Hours = 7}, 
                     }}, 
            new Employee{Name = "Herbert", WorkDays = new List<WorkDay> 
                     { 
                      new WorkDay{Date = new DateTime(2001,1,2), Hours = 8}, 
                      new WorkDay{Date = new DateTime(2001,1,4), Hours = 7}, 
                     }} 

           }; 
     pivotTarget.DataContext = PivotWorkingHours(demo); 

    } 

    private DataTable PivotWorkingHours(IEnumerable<Employee> employees) 
    { 
     DataTable result = new DataTable(); 
     result.Columns.Add("Date", typeof(DateTime)); 
     foreach (string name in employees.Select(x => x.Name).Distinct()) 
     { 
      result.Columns.Add(name, typeof(int)); 
     } 
     foreach (DateTime date in employees.SelectMany(e => e.WorkDays.Select(wd => wd.Date)).Distinct()) 
     { 
      DataRow row = result.NewRow(); 
      row["Date"] = date; 
      foreach (Employee employee in employees) 
      { 
       row[employee.Name] = employee.WorkDays.Where(wd => wd.Date == date).Sum(wd => wd.Hours); 
      } 
      result.Rows.Add(row); 
     } 


     return result; 
    } 
} 

class Employee 
{ 
    public String Name { get; set; } 
    public List<WorkDay> WorkDays { get; set; } 
} 

class WorkDay 
{ 
    public DateTime Date { get; set; } 
    public int Hours { get; set; } 
} 
Verwandte Themen