Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I construct a LINQ with multiple GroupBys?

I have an entity that looks like this:

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; }
}

A tiny sample of the data:

 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

Ultimately I am trying to get a result that is a list of tiers, within the tiers is a list of classes, and within the class is a distinct grouping of the TankName with the sums of Battles and Victories.

Is it possible to do all this in a single LINQ statement? Or is there another way to easily get the result? (I know I can easily loop through the DbSet several times to produce the list I want; I am hoping for a more efficient way of getting the same result with LINQ.)

like image 336
Sailing Judo Avatar asked Jun 12 '11 18:06

Sailing Judo


2 Answers

This should do it:

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
                        };
like image 200
The Evil Greebo Avatar answered Oct 12 '22 23:10

The Evil Greebo


You could also use Method syntax. This should give you the same as @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)
                        });

Which syntax you use comes down to preference. Remove the .Select to return the IGrouping which will enable you to enumerate the groups

var result = memberTanks.GroupBy(x => new {x.Tier, x.Class, x.TankName})
like image 25
NinjaNye Avatar answered Oct 12 '22 23:10

NinjaNye