2016-12-04 3 views
1

ich eine gruppierte Linq-Abfrage, die Gruppen Kunden mit diesem Produkt haben, und dann die Lage innerhalb dieser Kategorie:So gruppieren Linq-Abfrage durch dynamische Elemente

var categories = db.Items.GroupBy(p => p.Category). 
    Select(group => 
    new 
    { 
     name = group.Key, 
     data = new List<int>() 
     { 
      group.Count(p => p.City == "Sydney"), 
      group.Count(p => p.City == "Melbourne"), 
      group.Count(p => p.City == "Brisbane"), 
      group.Count(p => p.City == "Perth"), 
      group.Count(p => p.City == "Canberra"), 
     }, 
     total = group.Count() 
    }); 

Wie Sie sehen, ich bin hartzucodieren die Lage zu Erhalte die Anzahl für jeden Ort innerhalb einer Kategorie. Ich möchte dies nicht fest codieren, da die Speicherorte separat in der Datenbank gespeichert sind. Gibt es eine Möglichkeit, die Abfrage so zu ändern, dass die Anzahl dynamisch ist? Zum Beispiel für alles in db.locations?

Antwort

2

Sie können ein anderes GroupBy verwenden.

var categories = db.Items.GroupBy(p => p.Category).Select(group => 
new 
{ 
    Name = group.Key, 
    Data = group.GroupBy(g => g.City), 
    Total = group.Count() 
}); 

Sie können auch einen anderen anonymen Typ verwenden.

var categories = db.Items.GroupBy(p => p.Category).Select(group => 
new 
{ 
    Name = group.Key, 
    Data = group.GroupBy(g => g.City).Select(c => 
      new 
      { 
       CityName = c.Key, 
       Count = c.Count() 
      }), 
    Total = group.Count() 
}); 

Hier ist, wie man es benutzt. wenn du verwirrt bist.

foreach(var category in categories) 
{ 
    var name = category.Name; 
    var data = category.Data; 
    var total = category.Total; 

    foreach(var location in data) 
    { 
     var cityname = location.CityName; 
     var count = location.Count; 
    } 
} 

Beachten Sie, dass, wenn Sie woanders diese Abfrage als Parameter übergeben möchten, können Sie dynamic Stichwort statt var verwenden.

var wäre schnell. aber dynamic ist langsam, in diesem Fall empfehle ich Ihnen, benutzerdefinierte Klasse zu schreiben, um Ihre Daten statt anonymen Typ zu halten.

1
var categories = db.Items.GroupBy(p => p.Category). 
Select(group => 
new 
{ 
    name = group.Key, 
    data = new List<int>() 
    { 
     group.Count(p => p.City == db.locations.select(loc=>loc.ToString()).ToString()), 
    }, 
    total = group.Count() 
});