2013-09-27 57 views
5

Với lớp sau đây:C# groupby - Tạo nhiều cấp độ nhóm

public class Transaction 
{ 
    public string Category { get; set; } 
    public string Form { get; set; } 
} 

Làm thế nào để có được một nhóm các giao dịch đó được nhóm lại theo cả CategoryForm?

Về cơ bản tôi muốn nó ra như vậy:

Category 1 
    Form 1 
     Transaction1 
     Transaction2 
     Transaction3 
     ... 
    Form 2 
     Transaction1 
     Transaction2 
     Transaction3 
     ... 
Category 2 
    Form 1 
     Transaction1 
     Transaction2 
     Transaction3 
     ... 
    Form 2 
     Transaction1 
     Transaction2 
     Transaction3 
     ... 

Trả lời

6

tôi đã kết thúc với những điều sau đây, bởi vì nhóm cần phải được hoàn thành trước khi lặp đi lặp lại trên bộ sưu tập.

Seed Một số giao dịch

var cats = new[] { "Category 1", "Category 2", "Category 3" }; 
var frms = new[] { "Form 1", "Form 2", "Form 3" }; 
var transactions = new List<Transaction>(); 

for (var i = 0; i <= 150; i++) 
{ 
    transactions.Add(new Transaction 
    { 
     Category = i % 2 == 0 ? cats[0] : i % 3 == 0 ? cats[1] : cats[2], 
     Form = i % 5 == 0 ? frms[0] : i % 7 == 0 ? frms[1] : frms[2] 
    }); 
} 

Các Nhóm

var groupedTransactions = transactions.GroupBy(x => x.Category) 
    .Select(x => new 
    { 
     Category = x.Key, 
     Forms = x.ToList() 
      .GroupBy(y => y.Form) 
    }); 

Viết nó để Console

foreach (var group in groupedTransactions.OrderBy(x => x.Category)) 
{ 
    Console.WriteLine(group.Category); 
    foreach (var form in group.Forms.OrderBy(x => x.Key)) 
    { 
     Console.WriteLine("\t" + form.Key); 
     foreach (var transaction in form) 
     { 
      Console.WriteLine("\t\t" + transaction.Id); 
     } 
    } 
} 
6

Dưới đây là một ví dụ sử dụng vòng lặp foreach lồng nhau, tôi không chắc chắn làm thế nào bạn sẽ làm điều này trong một chuỗi duy nhất của báo cáo LINQ, có lẽ với rất nhiều của selectmanys?

var transactions = new[]{ 
    new{Category = "1", Form = "1", Title = "Trans1" }, 
    new{Category = "1", Form = "1", Title = "Trans2" }, 
    new{Category = "1", Form = "1", Title = "Trans3" }, 
    new{Category = "1", Form = "2", Title = "Trans1" }, 
    new{Category = "1", Form = "2", Title = "Trans2" }, 
    new{Category = "1", Form = "2", Title = "Trans3" }, 
    new{Category = "2", Form = "1", Title = "Trans1" }, 
    new{Category = "2", Form = "1", Title = "Trans2" }, 
    new{Category = "2", Form = "1", Title = "Trans3" }, 
    new{Category = "1", Form = "3", Title = "Trans1" }, 
    new{Category = "1", Form = "3", Title = "Trans2" }, 
    new{Category = "1", Form = "3", Title = "Trans3" }, 
}; 

foreach(var byCategory in transactions.GroupBy(x => x.Category)) 
{ 
    Console.WriteLine(byCategory.Key); 
    foreach(var byForm in byCategory.GroupBy(x => x.Form)) 
    { 
     Console.WriteLine("\t" + byForm.Key); 
     foreach(var trans in byForm) 
     { 
      Console.WriteLine("\t\t" + trans.Title); 
     } 
    } 
} 

Chỉ vì tôi đã tò mò những gì nó sẽ trông giống như tôi đã đưa ra những điều sau đây, BẠN NÊN KHÔNG SỬ DỤNG NÀY TRONG SẢN XUẤT MÃ vì nó là vô lý (nếu bạn có một cấu trúc dữ liệu như thế này nó sẽ bị phá vỡ lên thành cái gì đó giống như Dictionary<CategoryName, FormGroup> hay cái gì với các loại có ý nghĩa)

Dictionary<string, Dictionary<string, List<string>>> tooManyDictionaries = transactions 
     .GroupBy(x => x.Category) 
     .ToDictionary(
      catGroup => catGroup.Key, 
      catGroup => catGroup 
       .GroupBy(x => x.Form) 
       .ToDictionary(
        formGroup => formGroup.Key, 
        formGroup => formGroup.Select(x => x.Title).ToList())); 
Các vấn đề liên quan