0

Lets say I have an object with the following properties.

    public string VendorNumber { get; set; }
    public string PartNumber { get; set; }
    public string PartDivision { get; set; }

I have a list of about 300 of these objects. I am trying to group them first by VendorNumber, then by Division. I should be able to drill into them like so afterwards:

  1. Vendor A
    Divsion 1
    --Part 0001
    --Part 0002
    --Part 0003
    Divsiion 2
    --Part 0001
  2. Vendor B
    Division 1
    --Part 0023 ...etc...

I can do the first grouping easily like so:

var vendorGroups =
    from v in vendors
    group v by v.VendorNumber into vg
    select new { VendorNumber = vg.Key, Parts = vg, Count = vg.Count() };

I can't seem to get the nested grouping working though even after referring to some other posts here and on the MSDN. Thanks.


Here is what I ended up with from the suggestions:

I have made some progress using suggestions but I can't seem to access the second level when looping:

var vendorGroups = forecastHelpers
    .GroupBy(x => new { VendorNumber = x.VendorNumber, Division = x.PartDivision, Level = 1 })
    .GroupBy(x => new { VendorNumber = x.Key.VendorNumber }).OrderBy(x => x.Key.VendorNumber);

    foreach (var vendorGroup in vendorGroups)
{
    System.Diagnostics.Debug.WriteLine("VendorNumber: " + vendorGroup.Key.VendorNumber);
    foreach (var divisionGroup in vendorGroup)
    {
        System.Diagnostics.Debug.WriteLine("     Division: " + divisionGroup.Key.Division);
        foreach (var partNumber in divisionGroup)
        {
            System.Diagnostics.Debug.WriteLine("          PartNumber: " + partNumber.PartNumber);
        }
    }
}

Update 2: This could also be written like so:

var vendorGroupings = from f in forecastHelpers
                        group f by new { VendorNumber = f.VendorNumber, Division = f.PartDivision, Level = 2 } into vendorGroups
                        from divisionGroups in
                            (from division in vendorGroups
                            orderby division.PartDivision
                            group division by new { Division = division.PartDivision }) 
                        orderby vendorGroups.Key.VendorNumber
                        group divisionGroups by new { VendorNumber = vendorGroups.Key.VendorNumber, Level = 1 };


foreach (var vendorGroup in vendorGroupings)
{
    System.Diagnostics.Debug.WriteLine("VendorNumber: " + vendorGroup.Key.VendorNumber);

    foreach (var division in vendorGroup)
    {
        System.Diagnostics.Debug.WriteLine("     Division: " + division.Key.Division);

        foreach (var part in division)
        {
            System.Diagnostics.Debug.WriteLine("          PartNumber: " + part.PartNumber);
        }
    }
BBauer42
  • 3,549
  • 10
  • 44
  • 81

4 Answers4

2

Try this:

var vendorGroups = vendors.GroupBy(x => new { x.VendorNumber, x.PartDivision})
                          .GroupBy(x => x.Key.VendorNumber);

To access the second level, you need to do x.Key.PartDivision, not just x.Key (which works for the top level).


To address your edit:

var vendorGroups = forecastHelpers
    .GroupBy(x => new { VendorNumber = x.VendorNumber, Division = x.PartDivision, Level = 1 })
    .GroupBy(x => new { VendorNumber = x.Key.VendorNumber }).OrderBy(x => x.Key.VendorNumber);

foreach (var vendorGroup in vendorGroups)
{
    System.Diagnostics.Debug.WriteLine("VendorNumber: " + vendorGroup.Key.VendorNumber);  

    foreach(var division in vendorGroup)
    {
       System.Diagnostics.Debug.WriteLine("Division: " + division.Key.division); 
       foreach (var part in division)
       {
           System.Diagnostics.Debug.WriteLine("Part: " + part.PartNumber); 
       } 
    }
}
Bobson
  • 13,498
  • 5
  • 55
  • 80
1
var grouped = from v in vendors
              group v by new { VN = v.VendorNumber, VD = v.PartDivision} into grp
              orderby grp.Key.VN, grp.Key.VD
              select new {VN_VD=grp.Key, Items=grp};
Tim S.
  • 55,448
  • 7
  • 96
  • 122
Alireza
  • 10,237
  • 6
  • 43
  • 59
0
var vendorGroups =
    from v in vendors
    group v by v.VendorNumber into vg
    select new { VendorNumber = vg.Key, Parts = vg, Count = vg.Count() };
foreach (var vg in vendorGroups)
{
    var vendor = vg.VendorNumber;
    foreach (var divGroup in vg.Parts.GroupBy(x => x.PartDivision))
    {
        var division = divGroup.Key;
        foreach (var part in divGroup)
        {
            // do stuff with vendor, division, and part
        }
    }
}

It could probably be done with purely query syntax, but I find it clear and simple as-is.

Tim S.
  • 55,448
  • 7
  • 96
  • 122
0
var query = from x in set
            group x by x.VendorNumber into g
            select new 
            {
                VendorNumber = g.Key
                GroupedBy = g.ToLookup(x => x.PartDivision)                                 
            };

foreach(var x in query)
{
   var venderNumber = x.VendorNumber;
   foreach(var y in x.GroupBy)
   {
       var partDivision = y.Key
       foreach(Vendor item in y)
       {
           //do stuff with vendor
       }
   }
}
Aron
  • 15,464
  • 3
  • 31
  • 64