2011-08-04 71 views
75

如何使用lambda按多列分组?按多列分组使用lambda

我看到了如何使用linq来实体的例子,但我正在寻找lambda表单。

+0

你心里有一个特定的查询? –

回答

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

这实际上工作吗?我认为对于你分组的每个对象进行平等测试会失败,因为它们是对象而不是结构。 – Jacob

+0

@Aducci:谢谢。你能举例说明如何获得IEnumerable的组项目? – Naor

+4

@Jacob - 匿名类型是具有正确覆盖的'GetHashCode'&'Equals'方法的不可变类。他们正是为这种用例而设计的。 – Enigmativity

8

,如果你的表是这样的

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

aduchis回答上面 - 如果你然后需要筛选基于这些组的键,你可以定义一个类来包装的众多钥匙。

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

凡CustomerGroupingKey需要的组键:

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

     public string Country { get; } 

     public string Gender { get; } 
    } 
+0

可能会节省一些时间:最好使用对象初始化器的默认构造。以上示例代码中的方法将不会被像EF Core这样的ORM很好地处理。 – 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(); 

     } 
    }