2011-08-04 30 views
75

Làm cách nào để nhóm với nhiều cột bằng lambda?Nhóm bằng nhiều cột bằng lambda

Tôi đã xem các ví dụ về cách thực hiện nó bằng cách sử dụng LINQ cho các thực thể, nhưng tôi đang tìm biểu mẫu lambda.

+0

Bạn có một truy vấn cụ thể trong tâm trí? –

Trả lời

150
var query = source.GroupBy(x => new { x.Column1, x.Column2 }); 
+0

Điều này thực sự có hiệu quả không? Tôi sẽ nghĩ rằng kiểm tra bình đẳng cho từng đối tượng bạn nhóm theo sẽ thất bại vì chúng là đối tượng chứ không phải cấu trúc. – Jacob

+0

@Aducci: Cảm ơn. Bạn có thể ví dụ như thế nào tôi có thể nhận được IEnumerable của các mục nhóm? – Naor

+4

@Jacob - Các kiểu ẩn danh là các lớp không thay đổi với các phương thức 'GetHashCode' &' Equals' được ghi đè đúng cách. Chúng được thiết kế cho chính xác loại trường hợp sử dụng này. – Enigmativity

8

nếu bảng của bạn là như thế này

rowId  col1 col2 col3 col4 
1   a  e  12  2 
2   b  f  42  5 
3   a  e  32  2 
4   b  f  44  5 


var grouped = myTable.AsEnumerable().GroupBy(r=> new {pp1 = r.Field<int>("col1"), pp2 = r.Field<int>("col2")}); 
2

Tiếp tục để aduchis câu trả lời ở trên - nếu sau đó bạn cần phải lọc dựa trên những nhóm bằng các phím, bạn có thể định nghĩa một lớp học để quấn các phím nhiều.

return customers.GroupBy(a => new CustomerGroupingKey(a.Country, a.Gender)) 
       .Where(a => a.Key.Country == "Ireland" && a.Key.Gender == "M") 
       .SelectMany(a => a) 
       .ToList(); 

đâu CustomerGroupingKey mất các phím nhóm:

private class CustomerGroupingKey 
    { 
     public CustomerGroupingKey(string country, string gender) 
     { 
      Country = country; 
      Gender = gender; 
     } 

     public string Country { get; } 

     public string Gender { get; } 
    } 
+0

Có thể sẽ tiết kiệm thời gian cho một ai đó: tốt hơn là sử dụng các công trình mặc định với các đối tượng khởi tạo đối tượng. Cách tiếp cận trong mã mẫu ở trên sẽ không ** được xử lý bởi các ORM như EF Core. – Konstantin

0
 class Element 
     { 
      public string Company;   
      public string TypeOfInvestment; 
      public decimal Worth; 
     } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
     List<Element> elements = new List<Element>() 
      { 
       new Element { Company = "JPMORGAN CHASE",TypeOfInvestment = "Stocks", Worth = 96983 }, 
       new Element { Company = "AMER TOWER CORP",TypeOfInvestment = "Securities", Worth = 17141 }, 
       new Element { Company = "ORACLE CORP",TypeOfInvestment = "Assets", Worth = 59372 }, 
       new Element { Company = "PEPSICO INC",TypeOfInvestment = "Assets", Worth = 26516 }, 
       new Element { Company = "PROCTER & GAMBL",TypeOfInvestment = "Stocks", Worth = 387050 }, 
       new Element { Company = "QUASLCOMM INC",TypeOfInvestment = "Bonds", Worth = 196811 }, 
       new Element { Company = "UTD TECHS CORP",TypeOfInvestment = "Bonds", Worth = 257429 }, 
       new Element { Company = "WELLS FARGO-NEW",TypeOfInvestment = "Bank Account", Worth = 106600 }, 
       new Element { Company = "FEDEX CORP",TypeOfInvestment = "Stocks", Worth = 103955 }, 
       new Element { Company = "CVS CAREMARK CP",TypeOfInvestment = "Securities", Worth = 171048 }, 
      }; 

      //Group by on multiple column in LINQ (Query Method) 
      var query = from e in elements 
         group e by new{e.TypeOfInvestment,e.Company} into eg 
         select new {eg.Key.TypeOfInvestment, eg.Key.Company, Points = eg.Sum(rl => rl.Worth)}; 



      foreach (var item in query) 
      { 
       Console.WriteLine(item.TypeOfInvestment.PadRight(20) + " " + item.Points.ToString()); 
      } 


      //Group by on multiple column in LINQ (Lambda Method) 
      var CompanyDetails =elements.GroupBy(s => new { s.Company, s.TypeOfInvestment}) 
           .Select(g => 
              new 
              { 
               company = g.Key.Company, 
               TypeOfInvestment = g.Key.TypeOfInvestment,    
               Balance = g.Sum(x => Math.Round(Convert.ToDecimal(x.Worth), 2)), 
              } 
            ); 
      foreach (var item in CompanyDetails) 
      { 
       Console.WriteLine(item.TypeOfInvestment.PadRight(20) + " " + item.Balance.ToString()); 
      } 
      Console.ReadLine(); 

     } 
    }