Académique Documents
Professionnel Documents
Culture Documents
classIntroToLINQ
{
staticvoid Main()
{
// The Three Parts of a LINQ Query:
// 1. Data source.
int[] numbers = newint[7] { 0, 1, 2, 3, 4, 5, 6 };
// 2. Query creation.
// numQuery is an IEnumerable<int>
var numQuery =
from num in numbers
where (num % 2) == 0
select num;
// 3. Query execution.
foreach (int num in numQuery)
{
Console.Write("{0,1} ", num);
}
}
}
// Query execution.
foreach (int num in numQuery)
{
Console.Write("{0,1} ", num);
}
1.2.2. Forcer l’exécution immédiate
Les requêtes qui exécutent des fonctions d'agrégation sur un intervalle d'éléments
récupérés à partir d’une source de données doivent d'abord parcourir ces éléments.
Ceci est le cas des requêtes Count, Max, Average et First. Ces requêtes s’exécutent
donc sans expliciter la boucle d’exécution foreach. Ce type de requêtes retourne une
seule valeur et non pas une collection IEnumerable. L’exemple suivant retourne un
« count » qui calcule le nombre de nombres paires dans le tableau
d’entiers « numbers »:
List<int> numQuery2 =
(from num in numbers
where (num % 2) == 0
select num).ToList();
// or like this:
// numQuery3 is still an int[]
var numQuery3 =
(from num in numbers
where (num % 2) == 0
select num).ToArray();
var queryLondonCustomers =
from cust in customers
where cust.City == "London"
select cust;
On peut également utiliser les opérateurs logiques AND et OR pour appliquer autant de filtres
que l’on souhaite dans la clause where. Par exemple, afin de retourner une seul customer dont
la city est london et dont le nom est « Devon » on peut écrire le code suivant :
Pour retourner des customer de paris ou de London, on peut écrire la requête suivante :
2.2. Ordonnancement
Il est souvent utilise d’ordonner une list de résultat d’une requête. La clause orderby permet
d’ordonner la séquence retournée selon le comparateur par défaut du type à ordonner. Par
exemple, la requête suivante retourne une liste de customers ordonnés par nom. Parce que
name est de type string, le comparateur par défaut effectue un ordonnancement alphabétique
de A à Z.
var queryLondonCustomers3 =
from cust in customers
where cust.City == "London"
orderby cust.Name ascending
select cust;
Si l’on veut ordonner les éléments dans de z à a, utiliser la clause descending.
2.3. Groupement
La clause group permet de grouper les résultats selon une clé (key) qu’on spécifie. Par exemple,
on peut spécifier que les résultats doivent être groupés par city de façon à ce que tous les
customers de london ou de paris soient dans des groupes distincts. Dans ce cas, cust.city est
notre clé.
Quand on termine une requête avec la clause group, le résultat de la requête sera de la forme
d’une liste de listes. Chaque élément de la liste est un objet qui a une clé et une liste d’élément
groupés selon cette clé. Lorsqu’on parcourt le résultat de la requête (foreach), on doit utiliser
une deuxième boucle de parcours imbriquée. La boucle externe parcourt la liste de groupes, et
la boucle interne parcours les éléments d’un groupe.
Si l’on doit faire référence au résultat d’une opération de groupement, on peut utiliser le mot
clé into pour créer un identifiant qu’on peut utiliser dans d’ultérieures requêtes. La requête
suivante retourne les groupes qui contiennent plus que deux customers.
2.4. Jointure
L’opération de jointure associe deux séquences d’éléments qui ne sont pas explicitement liés
dans la source de données. On peut, par exemple, effectuer une jointure pour récupérer les
customers et les distributors qui ont la même location. Dans le langage LINQ, la clause join
s’applique aux collections d’objets et non directement aux tables d’une base de données.
Dans le langage LINQ on n’utilise pas la clause join aussi souvent que dans le SQL
Car les clés étrangères dans le langage LINQ sont représentées dans l’objet interrogé en tant
que propriétés. Par exemple l’objet customer contient une collection d’objets de type Order.
Dans ce cas au lieu d’effectuer une jointure, on peut accéder directement à la liste d’ordre
moyennant l’expression suivante :
2- Créer des éléments qui continent une ou plusieurs propriétés de l’élément source. On
peut utiliser un initialiseur d’objet avec soit un objet nommé ou un type anonyme.
L’exemple suivant illustre l’utilisation d’un type anonyme qui encapsule deux propriétés
de chaque élément « customer » :
var query =
from cust in Customer
select new {Name = cust.Name, City = cust.City};
//Query syntax:
IEnumerable<int> numQuery1 =
from num in numbers
where num % 2 == 0
orderby num
select num;
//Method syntax:
IEnumerable<int> numQuery2 =
numbers.Where(num => num % 2 == 0).OrderBy(n => n);
Le résultat des deux exemples est identique ainsi que le type de la variable des deux
IEnumerable<T>.
Pour mieux comprendre les requêtes basées sur les méthodes, on va les examiner de plus près.
La clause Where est exprimée en tant que méthode d’une instance de l’objet numbers.
numbers, rappelons-le, est de type IEnumerable<int>. Le type générique IEnumerable n’a pas
de methode Where, cependant, lorsqu’on invoque la liste auto-complete intelliSense de Visual
Studio, non seulement la méthode Where y figure, mais aussi d’autres méthodes tel que Select,
SelectMany, Join et OrderBy. Ce sont tous des opérateurs de requêtage standards.
Même si en apparence IEnumerable<T> a été redéfinie pour inclure toutes ces méthodes, il n’en
est rien. Il s’agit tout simplement de méthodes d’extension.