C# LINQ 嵌套组

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9578887/
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-09 07:58:31  来源:igfitidea点击:

Nested Group by LINQ

c#sqllinqgroup-by

提问by Nandu

I am unable to solve this problem with the LINQ Query.

我无法用 LINQ 查询解决这个问题。

So we have the table structure as follows: Id || bug_category || bug_name || bug_details || bug_priority

所以我们的表结构如下:Id || bug_category || 错误名称 || bug_details || 错误优先级

I want to group by bug_category first. For each bug_category, I want to in turn group by bug__priority.

我想先按 bug_category 分组。对于每个 bug_category,我想依次按 bug__priority 分组。

So basically I want something like :

所以基本上我想要这样的东西:

bug_category = AUDIO :: No of BUGS --> Critical = 3, Medium = 2 and Low = 7 bugs.
bug_category = VIDEO :: No of BUGS --> Critical = 5, Medium = 1 and Low = 9 bugs.

bug_category = AUDIO :: 错误数 --> 严重 = 3,中 = 2 和低 = 7 个错误。
bug_category = VIDEO :: 错误数 --> 严重 = 5,中 = 1 和低 = 9 个错误。

The below query returns all unique combinations of category AND customer_priority:

以下查询返回类别和 customer_priority 的所有唯一组合:

(where RawDataListis simply a List of data which has the above mentioned structure )

(其中RawDataList只是具有上述结构的数据列表)

        var ProceesedData = from d in RawDataList
                      group d by new { d.bug_category, d.bug_priority } into g
                      select new
                      {
                          g.Key.bug_category,
                          g.Key.bug_priority
                      };

The below query returns the category followed by a list of records in that category:

以下查询返回类别,后跟该类别中的记录列表:

            var ProceesedData = from d in RawDataList
                      group d by d.bug_category into g
                      select new { g.Key, records = g
                      };

But I am unable to proceed further as ProcessedData(the return variable) is an unknown type. Any thoughts on this?

但是我无法进一步处理,因为 ProcessedData(返回变量)是未知类型。对此有何想法?

采纳答案by Jon Skeet

I suspect you want (names changed to be more idiomatic):

我怀疑您想要(名称更改为更惯用):

var query = from bug in RawListData
            group bug by new { bug.Category, bug.Priority } into grouped
            select new { 
                Category = grouped.Key.Category,
                Priority = grouped.Key.Priority,
                Count = grouped.Count()
            };

Then:

然后:

foreach (var result in query)
{
    Console.WriteLine("{0} - {1} - {2}",
                      result.Category, result.Priority, result.Count);
}

Alternatively (but see later):

或者(但见下文):

var query = from bug in RawListData
            group bug by new bug.Category into grouped
            select new { 
                Category = grouped.Category,
                Counts = from bug in grouped
                         group bug by grouped.Priority into g2
                         select new { Priority = g2.Key, Count = g2.Count() }
            };

foreach (var result in query)
{
    Console.WriteLine("{0}: ", result.Category);
    foreach (var subresult in result.Counts)
    {
        Console.WriteLine("  {0}: {1}", subresult.Priority, subresult.Count);
    }
}

EDIT: As noted in comments, this will result in multiple SQL queries. To obtain a similar result structure but more efficiently you could use:

编辑:如评论中所述,这将导致多个 SQL 查询。要获得类似的结果结构但更有效,您可以使用:

var dbQuery = from bug in RawListData
              group bug by new { bug.Category, bug.Priority } into grouped
              select new { 
                  Category = grouped.Key.Category,
                  Priority = grouped.Key.Priority,
                  Count = grouped.Count()
              };

var query = dbQuery.ToLookup(result => result.Category,
                             result => new { result.Priority, result.Count };


foreach (var result in query)
{
    Console.WriteLine("{0}: ", result.Key);
    foreach (var subresult in result)
    {
        Console.WriteLine("  {0}: {1}", subresult.Priority, subresult.Count);
    }
}

回答by BitKFu

I think you're searching something like that:

我想你正在寻找这样的东西:

    var processedData =
        rawData.GroupBy(bugs => bugs.bug_category,
            (category, elements) =>
            new
                {
                    Category = category,
                    Bugs = elements.GroupBy(bugs => bugs.bug_priority,
                                        (priority, realbugs) =>
                                        new
                                            {
                                                Priority = priority,
                                                Count = realbugs.Count()
                                            })
                });
    foreach (var data in processedData)
    {
        Console.WriteLine(data.Category);

        foreach (var element in data.Bugs)
            Console.WriteLine("  " + element.Priority + " = " + element.Count);
    }

回答by AaronLS

This is an easier way to accomplish nested groupings. I've tested it for in memory collections, whether or not your particular DB provider will handle it well might vary, or whether it performs well is unknown.

这是完成嵌套分组的一种更简单的方法。我已经在内存集合中对它进行了测试,您的特定数据库提供程序是否能够很好地处理它可能会有所不同,或者它是否表现良好是未知的。

Assuming you had two properties, and wanted to group by both State and Country:

假设您有两个属性,并且想要按州和国家分组:

var grouped = People
  .GroupBy(l => new { l.State, l.Country})//group by two things
  .GroupBy(l=> l.Key.Country)//this will become the outer grouping


foreach(var country in grouped)
{
  foreach(var state in country)
  {
     foreach(var personInState in state)
     {
       string description = $"Name: {personInState.Name}, State: {state.StateCode}, Country: {country.CountryCode}";
       ...

     }
  }
}

回答by bhavsar japan

You can do it like this

你可以这样做

 var retList = (from dbc in db.Companies
                           where dbc.IsVerified && dbc.SellsPCBs && !dbc.IsDeleted && !dbc.IsSpam && dbc.IsApproved
                           select new
                           {
                               name = dbc.CompanyName,
                               compID = dbc.CompanyID,
                               state = dbc.State,
                               city = dbc.City,
                               businessType = dbc.BusinessType
                           }).GroupBy(k => k.state).ToList();


            List<dynamic> finalList = new List<dynamic>();

            foreach (var item in retList)
            {
                finalList.Add(item.GroupBy(i => i.city));
            }