2010-08-08 106 views
7

使用LINQ到SQL我如何组的以下2个表。LINQ的 - 组由多个表

订单表

CustomerID | Name |Date    
1   | order1 | 2010-01-01 
2   | order2 | 2010-01-01 
2   | order3 | 2010-04-01 

电话表

CustomerID | Name |Date    
1   | call1 | 2010-01-01 
3   | call2 | 2010-06-01 
2   | call3 | 2010-05-01 

我想组两个表的日期,结果

Date  | Orders | Calls 
2010-01-01 | 2  | 1 
2010-04-01 | 1  | 0 
2010-05-01 | 0  | 1 
2010-06-01 | 0  | 1 

我知道如何组一个表,

from o in Orders   
group o by o.Date.Date into og 
select new {Date = og.Key,Orders= og.Count()}; 

我如何组中的两个? thx!

回答

9

由于这两个表似乎有一个类似的结构,我建议将两者都投影到一个等价的形式,然后在这两个集合的连接上进行分组。

var orders = from o in Orders 
      select new { IsOrder = true, o.Date }; 
var calls = from c in Calls 
      select new { IsOrder = false, c.Date }; 

var result = from x in orders.Concat(calls)   
      group x by x.Date into og 
      select new {Date = og.Key, Orders= og.Count(o=>o.IsOrder), Calls = og.Count(c=>!c.IsTrue)}; 

由于Linq2Sql的惰性,这实际上可能会减少为单个查询。为了提高性能,我会确保这不是来自地狱的查询。

+0

你可以给我一个例子吗? – dano 2010-08-08 18:31:16

+0

thx! ,我希望我可以使用常规的LINQ/SQL命令,我没有考虑将这两个表格拼接起来。如果这是简单的TSQL,你会这样做吗? – dano 2010-08-08 18:35:19

+0

在TSQL我会使用一个完全外部连接,但是这并不容易在L2S,我希望我提供的解决方案比写一个完全外部连接简单。如果您想了解更多关于如何在Linq中使用FOJ的信息,请搜索。我搜查了 – 2010-08-08 18:42:46

1

可以使用联盟的方法:

var result = 
     (from c in Calls group c by c.Date into cg select new {Date = cg.Key, Calls = cg.Count(), Orders = 0}) 
     .Union(from o in Orders group o by o.Date into og select new {Date = og.Key, Calls = 0, Orders = og.Count()}) 
     .GroupBy(x => x.Date) 
     .Select(g => new {Date = g.Key, Calls = g.Max(r => r.Calls), Orders = g.Max(r => r.Orders)}); 

    foreach (var row in result) 
    { 
     Trace.WriteLine(row); 
    } 

这是非常相似,你会写(两个表的联合,然后外层查询到的结果合并成一排)的SQL

+0

thx 这真的类似于“约翰内斯鲁道夫”的答案。 – dano 2010-08-08 19:22:45

+0

是的,但它更可能导致一个SQL语句。最好把它们都放进去,看看调试器:) – 2010-08-08 19:30:20

+1

即时得到“所有使用UNION,INTERSECT或EXCEPT操作符组合的查询在目标列表中必须具有相同数量的表达式”,认为如果表有不同的日期,查询将会失败 – dano 2010-08-08 19:54:54