如何构造具有多个GroupBys的LINQ

本文关键字:GroupBys LINQ 何构造 | 更新日期: 2023-09-27 17:59:10

我有一个看起来像这样的实体:

public partial class MemberTank
{
    public int Id { get; set; }
    public int AccountId { get; set; }
    public int Tier { get; set; }
    public string Class { get; set; }
    public string TankName { get; set; }
    public int Battles { get; set; }
    public int Victories { get; set; }
    public System.DateTime LastUpdated { get; set; }
}

数据的一个小样本:

 Id   AccountId   Tier   Class  TankName   Battles  Victories
 ---  ---------   ----   -----  ---------  -------  ----------
 1    432423      5      Heavy  KV         105      58
 2    432423      6      Heavy  IS         70       39
 3    544327      5      Heavy  KV         200      102
 4    325432      7      Medium KV-13      154      110
 5    432423      7      Medium KV-13      191      101

最终,我试图得到一个结果,这是一个等级列表,等级中是一个类别列表,类别中是TankName与Battles和Victories之和的独特分组。

是否可以在一个LINQ语句中完成所有这些?或者还有其他方法可以轻松得到结果吗?(我知道我可以很容易地多次循环DbSet来生成我想要的列表;我希望用LINQ有一种更有效的方法来获得相同的结果。)

如何构造具有多个GroupBys的LINQ

这应该做到:

var output = from mt in MemberTanks
             group by {mt.Tier, mt.Class, mt.TankName} into g
             select new { g.Key.Tier, 
                          g.Key.Class, 
                          g.Key.TankName, 
                          Fights = g.Sum(mt => mt.Battles), 
                          Wins = g.Sum(mt=> mt.Victories
                        };

您也可以使用Method语法。这应该会给你和@TheEvilGreebo 一样的效果

var result = memberTanks.GroupBy(x => new {x.Tier, x.Class, x.TankName})
                        .Select(g => new { g.Key.Tier, 
                                           g.Key.Class, 
                                           g.Key.TankName, 
                                           Fights = g.Sum(mt => mt.Battles), 
                                           Wins = g.Sum(mt=> mt.Victories)
                        });

您使用的语法取决于偏好。拆下。选择返回IGrouping,它将使您能够枚举组

var result = memberTanks.GroupBy(x => new {x.Tier, x.Class, x.TankName})

我一直在努力获得关于邪恶格里博答案的有用结果。虽然答案确实产生了结果(在解决了回复中提到的编译问题后),但它并没有告诉我真正想要的是什么(这意味着我在问题中没有很好地解释自己)。

Feanz在我的问题中留下了一条评论,查看了带有LINQ示例的MS网站,尽管我以为我以前看过那里,但这次我找到了他们的嵌套组bys示例,我按照他们的方式进行了尝试。下面的代码给出了我想要的东西:

var result = from mt in db.MemberTanks
             group mt by mt.Tier into tg
             select new
             {
                 Tier = tg.Key,
                 Classes = from mt in tg
                           group mt by mt.Class into cg
                           select new
                           {
                               Class = cg.Key,
                               TankTypes = from mt in cg
                                           group mt by mt.TankName into tng
                                           select new
                                           {
                                               TankName = tng.Key,
                                               Battles = tng.Sum(mt => mt.Battles),
                                               Victories = tng.Sum(mt => mt.Victories),
                                               Count = tng.Count()
                                           }
                           }
             };

我将保留格里博先生的答案,因为大多数人可能会从中得到最好的结果。