2012-11-20 18 views
0

假設我有一個「數據庫」定義爲:LINQ - 不能添加列導致不改變多表分組

// Baked goods vendors 
    var vendor = new[] { 
    new { ID = 1, Baker = "Pies R Us", StMnemon = "NY", Items = 8, Rating = 9 }, 
    new { ID = 2, Baker = "Mikes Muffins", StMnemon = "CA", Items = 5, Rating = 9 }, 
    new { ID = 3, Baker = "Best Bakers", StMnemon = "FL", Items = 2, Rating = 5 }, 
    new { ID = 4, Baker = "Marys Baked Treats", StMnemon = "NY", Items = 8, Rating = 7 }, 
    new { ID = 5, Baker = "Cool Cakes", StMnemon = "NY", Items = 4, Rating = 9 }, 
    new { ID = 6, Baker = "Pie Heaven", StMnemon = "CA", Items = 12, Rating = 9 }, 
    new { ID = 7, Baker = "Cakes N More", StMnemon = "GA", Items = 6, Rating = 8 }, 
    new { ID = 8, Baker = "Dream Desserts", StMnemon = "FL", Items = 2, Rating = 7 } 
}; 

// Locations 
var location = new[] { 
    new {ID= 1, State = "New York", Mnemonic = "NY"}, 
    new {ID= 2, State = "Massachusetts", Mnemonic = "MA"}, 
    new {ID= 3, State = "Ohio", Mnemonic = "OH"}, 
    new {ID= 4, State = "California", Mnemonic = "CA"}, 
    new {ID= 5, State = "Florida", Mnemonic = "FL"}, 
    new {ID= 6, State = "Texas", Mnemonic = "TX"}, 
    new {ID= 7, State = "Georgia", Mnemonic = "GA" } 
}; 

我想建立一個查詢,將SQL查詢的等價:

SELECT State, Rating, SUM(Items) AS 'Kinds' 
FROM  vendor, location 
WHERE vendor.StMnemon = location.Mnemonic 
GROUP BY State, Rating 

兩人在此查詢自己感興趣的東西是:

  1. 本集團涉及多個表,
  2. 結果包含未出現在分組標準中的列的總和。

我在grouping by multiple tablessumming columns not in the group-by的帖子中看到過解決方案。問題是組合兩者並不真正複製關係查詢。

我嘗試用下面的代碼複製它在LINQ:

var query = from v in vendor 
      join l in location 
      on v.StMnemon equals l.Mnemonic 
      orderby v.Rating ascending, l.State 
      select new { v, l }; 

var result = from q in query 
      group q by new { 
       s = q.l.State, 
       r = q.v.Rating 
/* ==> */ , i = q.v.Items 
      } into grp 
     select new 
     { 
      State = grp.Key.s, 
      Rating = grp.Key.r 
/* ==> */ , Kinds = grp.Sum(k => grp.Key.i) 
     }; 

這導致:

================================= 
State   Rating Kinds 
Florida   5  2 
Florida   7  2 
New York  7  8 
Georgia   8  6 
California  9  5 
California  9  12 
New York  9  8 
New York  9  4 
================================= 

然而,上面給出的SQL查詢給出了這樣的結果:

========================= 
State  Rating Kinds 
Florida  5  2 
Florida  7  2 
New York 7  8 
Georgia  8  6 
California 9  17 
New York 9  12 
========================= 

該差異是因爲似乎有沒有地方除了在分組標準之外加入其他列,這當然會改變分組的結果。在上面的代碼中註釋掉/* ==> */評論中指出的兩行將給出與SQL結果相同的分組,但當然會刪除我想包含的求和字段。

我們如何在LINQ中對多個表進行分組幷包含附加條件而不更改分組結果?

回答

2

這樣的事情似乎返回相同的SQL查詢:

var result = from v in vendor 
      from l in location 
      where l.Mnemonic == v.StMnemon 
      group v by new { l.State, v.Rating } into grp 
      orderby grp.Key.Rating ascending, grp.Key.State 
      select new {State = grp.Key.State, Rating = grp.Key.Rating, Kinds = grp.Sum(p=>p.Items)}; 

foreach (var item in result) 
     Console.WriteLine("{0}\t{1}\t{2}", item.State, item.Rating, item.Kinds); 
+0

釘着它,瑪特。幹得不錯! – Buggieboy

2

你可以做組外聚集:

var query = from v in vendor 
      join l in location 
      on v.StMnemon equals l.Mnemonic 
      orderby v.Rating ascending, l.State 
      select new { v, l }; 

var result = from q in query 
      group q by new { 
       s = q.l.State, 
       r = q.v.Rating 
      } into grp 
     select new 
     { 
      State = grp.Key.s, 
      Rating = grp.Key.r, 
      Kinds = grp.Sum(g => g.Items) 
     }; 

分組是有點棘手把握 - 它返回一個IGrouping,它有一個屬性 - Key。該分組中的實際項目由GetEnumerator()函數返回,該函數允許您將該組視爲這些項目的集合,這意味着您可以對該組內的項目進行聚合。