C# Linq 分组

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34913/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 09:15:10  来源:igfitidea点击:

C# Linq Grouping

提问by Jonathan S.

I'm experimenting with Linq and am having trouble figuring out grouping. I've gone through several tutorials but for some reason can't figure this out.

我正在尝试使用 Linq,但在弄清楚分组方面遇到了麻烦。我已经阅读了几个教程,但由于某种原因无法弄清楚。

As an example, say I have a table (SiteStats) with multiple website IDs that stores a count of how many visitors by type have accessed each site in total and for the past 30 days.

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

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

In SQL, I can easily get the counts for SiteID 1 with the following:

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

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

and should get a row like...

并且应该得到像......

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

However I'm not sure how to get this result using Linq. I've tried:

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

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

but I'm not able to get back the total with something like statsRecord.Last30

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

Can someone please let me know where I'm going wrong? Any help is appreciated.

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

采纳答案by Ben Laan

Actually, although Thomas' code will work, it is more succint to use a lambda expression:

实际上,虽然 Thomas 的代码可以工作,但使用 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 )
};

which uses the Sum extension method without the need for a nested LINQ operation.

它使用 Sum 扩展方法,而无需嵌套的 LINQ 操作。

as per the LINQ 101 examples - http://msdn.microsoft.com/en-us/vcsharp/aa336747.aspx#sumGrouped

根据 LINQ 101 示例 - http://msdn.microsoft.com/en-us/vcsharp/aa336747.aspx#sumGrouped

回答by Tom Mayfield

Easiest way for me to illustrate is using in-memory objects so it's clear what's happening. LINQ to SQL should be able to take that same LINQ query and translate it into appropriate SQL.

对我来说,最简单的说明方法是使用内存中的对象,所以很清楚发生了什么。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; }
}