C#Linq分组

C#Linq分组

C# Linq Grouping

我正在使用Linq进行实验,但无法确定分组。 我已经看过一些教程,但是由于某种原因无法弄清楚。

例如,假设我有一个带有多个网站ID的表(SiteStats),该表存储过去30天按类型访问了每个网站的访问者总数。

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

在SQL中,我可以使用以下命令轻松获取SiteID 1的计数:

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

并应该像...

1
2
3
4
5
╔════════╦════════════╗
║ SiteId ║ Last30Total║
╠════════╬════════════╣
║      1 ║         50
╚════════╩════════════╝

但是我不确定如何使用Linq获得此结果。 我试过了:

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

但我无法使用statsRecord.Last30之类的东西来取回总数

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


实际上,尽管Thomas的代码可以工作,但是使用lambda表达式更为简洁:

1
2
3
4
5
6
7
8
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


我最容易说明的方法是使用内存中的对象,这样就可以清楚地了解正在发生的事情。 LINQ to SQL应该能够接受相同的LINQ查询并将其转换为适当的SQL。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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; }
}

推荐阅读