2009-05-19 3 views
4

J'ai du mal à créer des clauses Group By et Sort By par rapport à une liste myList générique. myList possède une liste de propriétés 'Settings' qui contient elle-même une liste de propriétés 'child' pour chaque entreprise.Application de LINQ aux objets Group By et Sort By à la liste générique <T> (C#)

Je souhaite regrouper par secteur d'activité et dans chaque industrie, trier par nom d'entreprise. Mon intention serait ceci:

string groupSetting = "Industry"; 
sortSetting = "BusinessName"; 
myList.GroupBy(p => p.Settings.Find(s => s.Name == groupSetting)).OrderBy(p => p.Settings.Find(t => t.Name == sortSetting)); 

Je suis toutefois obtenir l'erreur: 'System.Linq.IGrouping ne contient pas de définition de paramètres et aucun paramètre de méthode d'extension d'accepter un premier argument de type System.Linq. Igrouping pourrait être trouvé .... 'indiquant que je ne peux pas invoquer la clause order by sans une transformation ou un traitement supplémentaire.

J'ai essayé toutes sortes de choses pour séparer cela et le faire fonctionner, mais il me manque quelque chose. Toute aide appréciée

+1

Que voulez-vous dire "List myList myList a une liste de propriétés 'Paramètres'" Pouvez-vous poster un exemple de code pour configurer ceci (c'est-à-dire comment myList et ses éléments sont peuplés?) –

Répondre

12

Votre problème est que GroupBy ne retourne pas une seule liste de paramètres, il renvoie une "liste de listes". C'est le IGrouping que vous voyez.

Vous devez parcourir chaque groupe dans le IGrouping, trier ce groupe, puis parcourir chaque élément du groupe. Observer:

public static void Main(string[] args) 
{ 
    var groupSetting = "Industry"; 

    // step 1: group the data. Note this doesn't actually create copies of the data as 
    // it's all lazy loaded 
    // BEWARE. If a company doesn't have the "Industry" setting, this will throw an exception 
    var grouped = companies.GroupBy(c => c.Settings.First(s => s.Name == groupSetting).Value); 
    foreach(var group in grouped) 
    { 
     Console.WriteLine(group.Key);// this is the Value that came out of the GroupBy 

     // Note how we have to do the ordering within each individual group. 
     // It doesn't make sense to try group them in one hit like in your question 
     foreach(var item in group.OrderBy(bus => bus.Name)) 
      Console.WriteLine(" - " + item.Name); 
    } 
} 

Structures de données fournies par souci de clarté:

struct Setting { public string Name; public string Value; } 
struct Business { public string Name; public IEnumerable<Setting> Settings; } 

static IEnumerable<Business> companies = new[]{ 
    new Business{ Name = "XYZ Inc.", Settings = new[]{ 
     new Setting{ Name="Age", Value="27"}, 
     new Setting{ Name="Industry", Value="IT"} 
    }}, 
    new Business{ Name = "Programmers++", Settings = new[]{ 
     new Setting{ Name="Age", Value="27"}, 
     new Setting{ Name="Industry", Value="IT"} 
    }}, 
    new Business{ Name = "Jeff's Luxury Salmon", Settings = new[]{ 
     new Setting{ Name="Age", Value="63"}, 
     new Setting{ Name="Industry", Value="Sports"} 
    }}, 
    new Business{ Name = "Bank of Khazakstan", Settings = new[]{ 
     new Setting{ Name="Age", Value="30"}, 
     new Setting{ Name="Industry", Value="Finance"} 
    }}, 
}; 

Ceci produit la sortie suivante: Copier/coller le code et l'exécuter et jouer avec

IT 
- Programmers++ 
- XYZ Inc. 
Sports 
- Jeff's Luxury Salmon 
Finance 
- Bank of Khazakstan