2015-03-30 26 views
5

tôi có cấu trúc lớp sau:dữ liệu Pivot trong hai lồng nhau Danh sách <T> với 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; } 
} 

Có thể xoay các List<Employee> với LINQ vì vậy tôi có kết quả như thế này trong DataGridView tôi:

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

Đó là khó khăn vì nó là hai danh sách lồng nhau và tôi chỉ tìm thấy các ví dụ với danh sách duy nhất mà là khá đơn giản. Is it possible to Pivot data using LINQ?

tôi đã đến thời điểm này nhưng nó không hoàn toàn có được nêu ra:

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

tôi sẽ đánh giá cao bất cứ đề nghị.

Trả lời

1

Tôi nghĩ rằng bạn cần cái này: -

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

Đây là Working Fiddle với một số dữ liệu mẫu.

+1

Điều này có vẻ rực rỡ, cảm ơn rất nhiều @Rahul. – mdziadowiec

1

Ví dụ này sử dụng WPF nhưng bạn có thể sử dụng phương pháp "PivotWorkingHours" cho Winforms hoặc Webforms cũng ...

Output:

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> 

Triển khai:

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; } 
} 
Các vấn đề liên quan