2010-05-24 6 views
6

Je suis un programmeur depuis quelques années maintenant mais je suis un
nouveau venu à LINQ et C# alors pardonnez moi si ma question sonne
particulièrement stupide.Comment créer une requête LINQ dynamique en C# avec plusieurs clauses group by?

J'espère que quelqu'un peut me pointer dans le droit
direction. Ma tâche est de trouver la possibilité de former un groupe multiple dynamique par requête linq au sein d'un script C# en utilisant
une liste générique en tant que source.

Par exemple, dire que j'ai une liste contenant plusieurs éléments à la structure
suivante:

FieldChar1 - character 
FieldChar2 - character 
FieldChar3 - character 
FieldNum1 - numeric 
FieldNum2 - numeric 

En un mot, je veux être en mesure de créer une requête LINQ qui
résumera FieldNum1 et FieldNum2 groupé par un, deux ou
tous les trois champs FieldChar qui seront décidés à
runtime en fonction des besoins des utilisateurs ainsi que la sélection des champs FieldChar dans la même requête.

J'ai le dynamic.cs dans mon projet qui inclut une méthode d'extension GroupByMany mais je dois avouer que je ne suis pas vraiment sûr de savoir comment les utiliser. Je suis en mesure d'obtenir les résultats souhaités si j'utilise une requête avec un groupe câblé par requête mais pas dynamiquement. Toutes mes excuses pour toute nomenclature erronée, je suis nouveau dans cette langue mais tout conseil serait le bienvenu.

Un grand merci

Alex

Répondre

1

Voici l'exemple GroupBy de base. Disons que nous avons une classe simple comme ceci:

public class Person 
{ 
    public string Name { get; set; } 

    public int Age { get; set; } 

    public char Sex { get; set; } 
} 

Ensuite, vous pouvez utiliser GroupBy comme ceci:

var people = new List<Person> { 
    new Person { Name = "Joe", Age = 30, Sex = 'M' }, 
    new Person { Name = "Liz", Age = 22, Sex = 'F' }, 
    new Person { Name = "Jim", Age = 22, Sex = 'M' }, 
    new Person { Name = "Alice", Age = 30, Sex = 'F' }, 
    new Person { Name = "Jenny", Age = 22, Sex = 'F' } 
}; 
var groups = people.GroupBy(p => p.Age); 

foreach (var group in groups) 
{ 
    foreach (var person in group) 
     Console.WriteLine(person.Name + " - " + person.Age); 
} 

En ce qui concerne le regroupement par des propriétés multiples, voir ceux-ci:
http://weblogs.asp.net/zeeshanhirani/archive/2008/05/07/group-by-multiple-columns-in-linq-to-sql.aspx
LINQ TO DataSet: Multiple group by on a data table

Fondamentalement, c'est la même syntaxe avec un type anonyme, par exemple:

var groups = people.GroupBy(p => new { p.Age, p.Sex }); 

Notez que vous pouvez rechercher l'utilisation de plusieurs OrderBy s:

var query = people.OrderBy(p => p.Age).ThenBy(p => p.Sex); 
//You can have unlimited ThenBy's 

Notez également que le résultat de la dernière déclaration GroupBy et le résultat de cette déclaration OrderBy est pas la même chose.

+0

Un grand merci pour votre réponse. J'apprécie et me donne quelque chose de nouveau à regarder. Mais est-il possible d'obtenir votre exemple de ... var groups = people.GroupBy (p => new {p.Age, p.Sex}); dans une ligne de code où la clause group by (p.Age, p.Sex) peut être remplacée par une chaîne de variables construite préalablement qui pourrait être n'importe quelle combinaison d'âge et/ou de sexe? Je viens d'un arrière-plan FoxPro/SQL où vous pouvez construire dynamiquement votre requête en utilisant la concaténation de chaînes. Encore une fois, j'apprécie votre aide. – FordPrefect141

+0

@ FordPerfect141 - Avec LINQ, vous ne pouvez pas vraiment concaténer les chaînes, car LINQ doit être fortement typé. Vous pouvez réaliser quelque chose de similaire en créant dynamiquement une telle expression. – Venemo

+0

Ah-ha. Donc, dans votre exemple, si l'utilisateur voulait grouper quelquefois par sexe et par âge, et parfois seulement par âge, comment vous y prendriez-vous sans réellement coder la clause group by? Je m'excuse encore, c'est tout nouveau pour moi. Merci beaucoup encore. – FordPrefect141

0

GroupBy (groupByName + "" + groupByDirection, nouveau {})

Ainsi, vous pouvez passer groupByName et groupByDirection, quand vous faites un pas à travers, vous pouvez voir quelque chose comme

GroupBy ("lastName desc », nouveau {})

ou

GroupBy ("prenom asc", nouveau {})