2008-08-29 68 views
18

我正在试验Linq,并且在分组时遇到困难。我已经通过了几个教程,但由于某种原因无法弄清楚。C#Linq分组

作为一个例子,假设我有一个表(SiteStats),其中包含多个网站ID,用于存储每个网站访问总数和过去30天的访问人数。

╔════════╦═════════════╦════════╦══════╗ 
║ SiteId ║ VisitorType ║ Last30 ║ Total║ 
╠════════╬═════════════╬════════╬══════╣ 
║  1 ║   1 ║  10 ║ 100 ║ 
║  1 ║   2 ║  40 ║ 140 ║ 
║  2 ║   1 ║  20 ║ 180 ║ 
╚════════╩═════════════╩════════╩══════╝ 

在SQL中,我可以很容易地获得SITEID 1计数有以下几点:

SELECT SiteId, 
     SUM(Last30) AS Last30Sum 
FROM Sites 
WHERE SiteId = 1 
GROUP BY SiteId 

,并应该得到一排像...

╔════════╦════════════╗ 
║ SiteId ║ Last30Total║ 
╠════════╬════════════╣ 
║  1 ║   50 ║ 
╚════════╩════════════╝ 

不过我不知道如何使用Linq获得这个结果。我已经试过:

var statsRecord = from ss in db.SiteStats 
    where ss.SiteId == siteId 
    group ss by ss.SiteId into ss 
    select ss; 

,但我不能回去的东西,如statsRecord.Last30

有人可以请让我知道总我要去哪里错了吗?任何帮助表示赞赏。

回答

34

实际上,虽然托马斯的代码将工作,这是更succint使用lambda表达式:

var totals = 
from s in sites 
group s by s.SiteID into grouped 
select new 
{ 
    SiteID = grouped.Key, 
    Last30Sum = grouped.Sum(s => s.Last30) 
}; 

其中使用Sum扩展方法,而不需要一个嵌套LINQ操作。

按照LINQ的101例 - http://msdn.microsoft.com/en-us/vcsharp/aa336747.aspx#sumGrouped

+0

虽然OP没有问,你能告诉我们如何能在LINQ的方法语法来写? – FMFF 2015-03-03 17:13:35

4

我说明的最简单的方法是使用内存中的对象,所以很清楚发生了什么。 LINQ to SQL应该能够采用相同的LINQ查询并将其转换为适当的SQL。

public class Site 
{ 
    static void Main() 
    { 
     List<Site> sites = new List<Site>() 
     { 
      new Site() { SiteID = 1, VisitorType = 1, Last30 = 10, Total = 100, }, 
      new Site() { SiteID = 1, VisitorType = 2, Last30 = 40, Total = 140, }, 
      new Site() { SiteID = 2, VisitorType = 1, Last30 = 20, Total = 180, }, 
     }; 

     var totals = 
      from s in sites 
      group s by s.SiteID into grouped 
      select new 
      { 
       SiteID = grouped.Key, 
       Last30Sum = 
        (from value in grouped 
        select value.Last30).Sum(), 
      }; 

     foreach (var total in totals) 
     { 
      Console.WriteLine("Site: {0}, Last30Sum: {1}", total.SiteID, total.Last30Sum); 
     } 
    } 

    public int SiteID { get; set; } 
    public int VisitorType { get; set; } 
    public int Last30 { get; set; } 
    public int Total { get; set; } 
}