2013-10-08 3 views
0

Допустим, у меня есть объект со следующими свойствами.Вложенные группы, использующие linq?

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

У меня есть список около 300 из этих объектов. Я пытаюсь сначала сгруппировать их по VendorNumber, затем по разделу. Я должен быть в состоянии сверлить в них, как так далее:

  1. Производитель A
    Divsion 1
    --Part 0001
    --Part 0002
    --Part 0003
    Divsiion 2
    - Часть 0001
  2. Vendor B
    Division 1
    --Part 0023 ... и т.д. ...

я могу сделать первую группу легко выглядеть примерно так:

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

Я не могу показаться, чтобы получить вложенная группировка работает, хотя даже после того, ссылаясь на некоторые другие посты здесь и на сайте MSDN. Благодарю.


Вот что я закончил с из предложений:

Я сделал некоторые успехи, используя предложения, но я не могу показаться, чтобы получить доступ ко второму уровню, когда зацикливание:

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: Это также может быть записана следующим образом:

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); 
     } 
    } 
+0

ли значения PartDivision уникальными для каждого поставщика, или может то же значение, можно использовать два разных производителей? – yoozer8

+0

Пожалуйста, смотрите на SO Ссылка ниже, [http://stackoverflow.com/questions/9578887/nested-group-by-linq][1] [1]: HTTP://переполнение стека.com/questions/9578887/nested-group-by-linq –

+0

Значения PartDivision НЕ уникальны для каждого поставщика. – BBauer42

ответ

0

Попробуйте это:

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

Чтобы получить доступ ко второму уровню, что вам нужно сделать x.Key.PartDivision, а не только x.Key (который работает на верхнем уровне).


Для решения правку:

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); 
     } 
    } 
} 
+0

Я не могу получить доступ к второму уровню ... Пожалуйста, см. Мое обновленное сообщение. – BBauer42

+0

Nevermind Я идиот. Я обновил сообщение, чтобы показать цикл. Благодарю. – BBauer42

+0

@ BBauer42 - Отредактировано для отображения вложенных циклов. Посмотрите, поможет ли это. – Bobson

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

Возможно, это может быть сделано с использованием синтаксиса запроса, но я нахожу его понятным и простым как есть.

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

@Tim S. Спасибо за редактирование моего кода – Alireza

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 
     } 
    } 
} 
Смежные вопросы