2012-11-20 10 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()函数返回,该函数允许您将该组视为这些项目的集合,这意味着您可以对该组内的项目进行聚合。