2015-03-30 9 views
5

Ho la seguente struttura di classe:dati Pivot in due Lista nidificato <T> con 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; } 
} 

E 'possibile ruotare il List<Employee> con LINQ così ho risultato come questo nel mio DataGridView:

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

È complicato perché si tratta di due liste annidate e ho trovato solo esempi con un singolo elenco che sono piuttosto semplici. Is it possible to Pivot data using LINQ?

ho arrivati ​​a questo punto, ma non è ancora lontani:

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

Gradirei qualche suggerimento.

risposta

1

penso che avete bisogno di questo: -

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

Ecco la Working Fiddle con alcuni dati di esempio.

+1

Questo sembra geniale, grazie mille @Rahul. – mdziadowiec

1

Questo esempio utilizza WPF, ma si potrebbe usare il metodo del "PivotWorkingHours" per WinForms o Webforms così ...

uscita:

enter image description here

Window:

<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> 

Implementazione:

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; } 
}