c# 3 et linq
TRANSCRIPT
-
8/14/2019 c# 3 Et Linq
1/51
P a g e | 1
C# 3 et LINQ
Arrive en version Alpha il y a quelques temps, la troisime version du langage C# rserve des
nouveauts qui savre fort pratiques pour les dveloppeurs.
Accompagn du projet LINQ(utilisable en C#, VB.NET et les autres langages .NET), qui concerne tout
ce qui est accs aux donnes, cette nouvelle version du langage cr par Microsoft tout pour
russir une avance majeure dans le milieu des dveloppeurs.
Cet article a pour but de vous permettre de dcouvrir ce nouveau langage innovateur, et ce nouveau
projet dont certaines parties risquent, terme, dintgrer ADO.NET 3.0
Cet article s'inspire, pour beaucoup, des "labs" qui sont fournis avec les CTP de LINQ.
-
8/14/2019 c# 3 Et Linq
2/51
P a g e | 2
SommaireIntroduction ............................................................................................................................................. 3
Le langage C# 3 ........................................................................................................................................ 4
Utilisation de variables locales types implicitement ......................................................................... 4
Les mthodes dextension...................................................................................................................7
Les expressions lambdas ..................................................................................................................... 8
Les initialiseurs dobjets ....................................................................................................................12
Les types anonymes .......................................................................................................................... 14
Le projet LINQ ........................................................................................................................................ 15
LINQ ................................................................................................................................................... 15
Interroger une liste gnrique .......................................................................................................... 15
Les oprateurs standards .................................................................................................................. 19
L'oprateur OfType ....................................................................................................................... 19
Les oprateurs Min, Max, Sum et Average (Moyenne)................................................................. 20
L'oprateur Select ......................................................................................................................... 21
L'oprateur Where ........................................................................................................................ 21
L'oprateur Count ......................................................................................................................... 22
Les oprateurs ToArray et ToList ................................................................................................... 23
DLINQ ................................................................................................................................................ 24
LINQ for SQL .................................................................................................................................. 24
Le designer DLINQ ......................................................................................................................... 34
XLINQ ................................................................................................................................................. 41
Charger un document XML............................................................................................................ 42
Crer des lments XML................................................................................................................ 43
Parcourir un XML ........................................................................................................................... 44
Manipuler un XML ......................................................................................................................... 45
Travailler avec les attributs ........................................................................................................... 47
Modifier/Supprimer/Mettre jour des attributs .......................................................................... 47
Accder aux attributs .................................................................................................................... 48
Produire du XML ............................................................................................................................ 48
Requter du XML avec XLINQ ........................................................................................................ 49
Conclusions ............................................................................................................................................ 49
Remerciements ..................................................................................................................................... 50
-
8/14/2019 c# 3 Et Linq
3/51
P a g e | 3
Introduction
Depuis les premires versions Alpha, tlchargeables depuis la PDC (Professional Developer
Conference) 2005, la nouvelle version du langage C#, le C# 3, na cess de subir des modifications et
des amliorations pour tenter dintgrer de nouvelles fonctionnalits la dernire version en date, le
C# 2.
LINQ, de son vrai nom "Language Integrated Query", reprsente une volution majeure de laccs
aux donnes dans le Framework .NET.
Il sagit dun projet de requtage de donnes, se divisant en plusieurs grandes parties :
LINQ To ADO.NET, qui inclut:o LINQ To DataSeto LINQ To Entitieso LINQ To SQL (anciennement connu sous le nom de DLINQ, et qui permet dexcuter
des requtes sur une base de donnes, de faire du mapping objet-relationnel)
Le support de LINQ pour les autres type de donnes:o LINQ To XML (anciennement connu sous le nom XLINQ, qui permet dexcuter des
requtes sur des documents XML)
o LINQ To Objects
Pour bien comprendre cette division, je vous conseille de regarder le message de Soma Somasegar :
http://blogs.msdn.com/somasegar/archive/2006/06/21/641795.aspx
Au cours de cet article, je vais donc tenter de vous parler, au mieux, de toutes ces nouveauts que
nous rserve Microsoft.
Note : Tous les exemples de cet article se basent sur la CTP (Community Technology Preview) de Mai
2006 de LINQ, que vous pouvez tlcharger ici :
http://www.microsoft.com/downloads/details.aspx?familyid=1e902c21-340c-4d13-9f04-
70eb5e3dceea&displaylang=en
http://blogs.msdn.com/somasegar/archive/2006/06/21/641795.aspxhttp://blogs.msdn.com/somasegar/archive/2006/06/21/641795.aspxhttp://www.microsoft.com/downloads/details.aspx?familyid=1e902c21-340c-4d13-9f04-70eb5e3dceea&displaylang=enhttp://www.microsoft.com/downloads/details.aspx?familyid=1e902c21-340c-4d13-9f04-70eb5e3dceea&displaylang=enhttp://www.microsoft.com/downloads/details.aspx?familyid=1e902c21-340c-4d13-9f04-70eb5e3dceea&displaylang=enhttp://www.microsoft.com/downloads/details.aspx?familyid=1e902c21-340c-4d13-9f04-70eb5e3dceea&displaylang=enhttp://www.microsoft.com/downloads/details.aspx?familyid=1e902c21-340c-4d13-9f04-70eb5e3dceea&displaylang=enhttp://blogs.msdn.com/somasegar/archive/2006/06/21/641795.aspx -
8/14/2019 c# 3 Et Linq
4/51
P a g e | 4
Le langage C# 3
Dvelopp par Microsoft, et en particulier par Anders Hejlsberg (dj inventeur du Turbo Pascal et
du langage Delphi), le C# (prononc "Si Sharp") est un langage en constante volution qui ne cesse de
rserver des surprises.
Dans sa troisime version (actuellement en Alpha), le C# possde un bon nombre de fonctionnalits
que beaucoup de dveloppeurs C# auraient aim avoir dans la version actuelle du langage.
Plutt que de discuter, je vous propose de rentrer directement dans le vif du sujet.
Utilisation de variables locales types implicitement
Lutilisation de variables locales types implicitement est une des nouvelles fonctionnalits offertes
par C# 3, qui permet aux dveloppeurs de dclarer des variables dont le type nest pas indiqu
explicitement. En effet, le type de ces variables est dcouvert, par le compilateur, en fonction de la
partie droite de laffectation.
Cette nouvelle fonctionnalit permet de librer les dveloppeurs de la contrainte davoir spcifier,
chaque fois, le type de leurs variables ou de leurs requte.
Voyons cela travers un exemple :
Dans Visual Studio 2005, pour crer un projet C# 3, il vous faut slectionner "New Project" => "LINQ
Preview" et choisir le type de projet que vous voulez crer. Vous allez avoir la boite de dialogue
suivante, qui vous explique que C# 3 / VB 9 est un langage encore en Beta, et que certaines
fonctionnalits ne fonctionneront peut-tre pas correctement :
Cliquez alors sur "OK" pour pouvoir commencer dvelopper.
-
8/14/2019 c# 3 Et Linq
5/51
P a g e | 5
Pour comprendre ce nouveau concept de variables types implicitement, commencez par regarder
ce bout de code :
int x = 5;
string s = "Article C# 3 / LINQ";
int [] tab = newint [] { 1, 2, 3, 4, 5 };
Console.WriteLine("Valeur de x: {0}", x);Console.WriteLine("Valeur de s: {0}", s);
Console.WriteLine("Liste des valeurs de tab:");
foreach(int i in tab)
{
Console.WriteLine(i);
}
Jusque ici, rien de bien extraordinaire : on commence par dclarer un entier puis une chane de
caractres et enfin, un tableau dentier.
Maintenant, que ce passerait-il si le type de vos variables ntait pas connu ? Il vous serait tout
simplement impossible de les dclarer et donc de les utiliser.
Cest justement ce point qui est amlior grce aux variables types implicitement. La preuve par le
code :
var x = 5;
var s = "Article C# 3 / LINQ";
var tab = newint [] { 1, 2, 3, 4, 5 };
Console.WriteLine("Valeur de x: {0}", x);Console.WriteLine("Valeur de s: {0}", s);
Console.WriteLine("Liste des valeurs de tab:");
foreach(int i in tab){
Console.WriteLine(i);
}
Dans ce code, nous dclarons des variables mais sans en prciser le type. A la place, nous utilisons le
mot cl var. A la compilation, le type de vos variables sera dduit automatiquement
Le rsultat est donc sans surprises :
-
8/14/2019 c# 3 Et Linq
6/51
P a g e | 6
Bien entendu, vous pouvez utiliser var avec des variables simples mais galement avec des
collections :
var list = newDictionary();
list.Add("PremiereCle", 1);list.Add("PremiereCle", 2);
list.Add("PremiereCle", 1);
list.Add("DeuxiemeCle", 1);
list.Add("DeuxiemeCle", 3);list.Add("DeuxiemeCle", );
Il y a tout de mme des restrictions que vous devez prendre en compte lorsque vous dclarez une
variable avec le mot cl var.
Par exemple, le type de la variable tant dduit de linitialiseur, une dclaration implicitement type
doit obligatoirement avoir un initialiseur. Le bout de code suivant provoquerait donc une erreur :
var list;
Et devrait tre remplac par quelque chose comme:
var list = newList();
Voyons prsent une autre des nouvelles fonctionnalits offertes par C# 3: les mthodes
dextension.
-
8/14/2019 c# 3 Et Linq
7/51
P a g e | 7
Les mthodes dextension
Les mthodes dextensionsvous permettent dtendre les fonctionnalits offertes par un type, en
dfinissant de nouvelles mthodes qui seront invoques en utilisant la syntaxe normale dappel
dune mthode.
Les mthodes dextension sont des mthodes statiques, qui sont dclares en utilisant le mot cl this
comme modificateur de porte, pour le premier paramtre de la mthode.
Pour bien comprendre ce nouveau concept, on va repartir dun nouvel exemple :
Crer un nouveau projet de type "LINQ Preview" dans Visual Studio et ajouter la classe suivante :
publicstatic classToUpperCaseClass{
publicstaticstring ToUpperCase(string s){
return s.ToUpper();}
}
Comme vous pouvez le constatez, cette classe na rien dextraordinaire: elle contient une mthode
statique qui prend en paramtre une chane de caractres et qui retourne cette mme chane, aprs
lavoir passe en majuscule.
Pour utiliser cette classe/mthode, rien de bien compliqu :
string s = "Article C# 3 et LINQ";
Console.WriteLine(ToUpperCaseClass.ToUpperCase(s));
Voyons maintenant comment nous pourrions utiliser cette mthode comme une mthode
dextension.
Commencer par modifier le code de votre mthode :
publicstaticstring ToUpperCase(thisstring s)
Et enfin, lappel de cette mthode :
Console.WriteLine(s.ToUpperCase());
-
8/14/2019 c# 3 Et Linq
8/51
P a g e | 8
Le rsultat est, comme vous pouvez limaginer, identique dans les deux cas:
Dans la premire version, vous avez pass votre variable de type chane de caractres en paramtre
votre mthode statiques. Dans la seconde version, vous avez appel directement cette mthode
sur votre objet.
Attention: grce cette mthode dextension, vous avez russi rajouter une mthode un objet
particulier et non lune des classes de base de Framework .NET !
Si on regarde le code qui a t gnre pour crire cette mthode d'extension, on voit bien qu' la
compilation, l'appel de la mthode a simplement t remplac par l'appel une mthode statique:
string text1 = "Article C# 3 et LINQ";
Console.WriteLine(ToUpperCaseClass.ToUpperCase(text1));
Les expressions lambdas
Pour comprendre le concept des expressions lambda, il faut se rappeler dune des fonctionnalits
offertes par C# 2 : les mthodes anonymes. Ces mthodes permettaient aux dveloppeurs dcrire
des blocs de code en ligne, lorsque des dlgus taient ncessaires.
Par exemple, on pouvait tout fait crire quelque chose comme ceci :
List list = newList(newint [] { -1, 2, -5, 45, 5 });
ListpositiveNumbers = list.FindAll(delegate(int i) { return i > 0;});
Les expressions lambda reprsentent en fait un moyen plus simple dcrire les mthodes anonymes.
-
8/14/2019 c# 3 Et Linq
9/51
P a g e | 9
Une expression lambda est compose de trois parties :
Une liste de paramtre Le signe => Une expression
Voici un exemple dexpression lambda :
(int i) => i % 2 == 0
Au niveau de la liste de paramtres, il y a deux choses savoir :
Les paramtres peuvent tre typs explicitement ou implicitement. Dans le second cas, letype est dduit de lexpression qui constitue votre expression.
Sil ny a quun seul paramtre typ implicitement, les parenthses sont facultatives
Voyons un peu comment nous pourrions utiliser cela dans notre code :
List list = newList(newint [] { -1, 2, -5, 45, 5 });
var positiveNumbers = list.FindAll((int i) => i > 0);
foreach(int positiveNumber in positiveNumbers){
Console.WriteLine(positiveNumber);
}
Le code de cette application, utilisant une expression lambda, fournit le mme rsultat que la version
utilisant les mthodes anonymes : il est simplement plus clair lire.
Bien entendu, rien ne vous empche dutiliser plusieurs paramtres dans votre expression lambda.
-
8/14/2019 c# 3 Et Linq
10/51
P a g e | 10
Commencez par crer une petite mthode dextension que nous utiliserons plus tard. Noubliez
quune mthode dextension est une mthode statiques. Pour bien faire, crer cette mthode dans
une nouvelle classe, afin dorganiser au mieux votre code.
publicstaticclassFilterClass{
publicdelegateboolKeyValueFilter(K key, V value);
publicstaticDictionary FilterBy(thisDictionaryitems,
KeyValueFilter filter){
var result = newDictionary();
foreach (KeyValuePair element in items)
{if (filter(element.Key, element.Value))
result.Add(element.Key, element.Value);}
return result;
}
}
Ensuite, il ne vous reste plus qu construire votre expression lambda comme prcdemment mais
en modifiant votre expression pour travailler avec plusieurs paramtres :
// Expression lambda avec plusieurs paramtresvar listLanguages = newDictionary();
listLanguages.Add("C#", 5);
listLanguages.Add("VB", 3);listLanguages.Add("Java", -5);
var bestLanguages = listLanguages.FilterBy((string name, int score) => name.Length
== 2 && score > 0);
foreach(KeyValuePairlanguage in bestLanguages){
Console.WriteLine(language.Key);
}
Ici, on travaille bien sur une expression lambda qui possde plusieurs paramtres.
-
8/14/2019 c# 3 Et Linq
11/51
P a g e | 11
Vous pourriez, et vous auriez tout fait raison, trouver tout cela un petit peu magique.
Comment se fait-il que des mthodes telles que FindAll ou FilterBy accepte en paramtre une
expression lambda, alors que normalement, il devrait y avoir un dlgu ?
La rponse est simple: c'est grce au compilateur. En effet, c'est lui qui sait de quels types doiventtre les paramtres des mthodes. Il est donc en mesure de dterminer si, oui ou non, les
expressions lambda correspondent au type attendu.
Donc finalement, rien de magique ici: on a simplement affaire un compilateur intelligent
Vous pourriez galement vous demander ceci: "Pourquoi les mthodes d'extension et les expressions
lambda existent ?"
En effet, qu'est-ce qui les rend si importantes pour les dveloppeurs, sachant que les techniquesemployes jusque l fonctionnaient trs bien ?
En ce qui concerne les mthodes d'extension, la rponse est simple: il ne s'agit que d'une simple aide
au dveloppeur, de la part du compilateur, afin de lui faciliter la vie dans l'criture de son programme
et en particulier des requtes LINQ (que nous verrons par la suite).
Pour les expressions lambda, le but est de fournir, aux dveloppeurs, un moyen leur permettant de
passer du code en paramtres de leurs mthodes.
Au jour d'aujourd'hui, vous pouvez tout fait raliser cela avec les delegates: vous dclarez un
delegate prenant comme paramtre un pointeur vers une fonction. Lors de l'appel d'une de vos
mthodes, vous passez en paramtre ce delegate. Au final, l'appel de la mthode, le contenu de la
mthode pointe par le delegate sera excut.
Et bien les expressions lambda ne sont qu'une autre manire de faire cela: elles vous permettent de
passer, en paramtres de vos mthodes, des mthodes anonymes dont l'criture a t simplifie.
Pour bien assimiler ce concept d'expressions lambda, je vous conseille le webcast raliser par Mitsu
Furuta:
http://www.microsoft.com/france/events/event.aspx?EventID=1032300129
http://www.microsoft.com/france/events/event.aspx?EventID=1032300129http://www.microsoft.com/france/events/event.aspx?EventID=1032300129http://www.microsoft.com/france/events/event.aspx?EventID=1032300129 -
8/14/2019 c# 3 Et Linq
12/51
P a g e | 12
Les initialiseurs dobjets
Dclarer une variable en C# se fait en deux tapes :
Dclaration de la variable Initialisation de cette variable
C# 3 propose un nouveau concept qui vous permet de dclarer et dinstancier, en mme temps, un
membre (proprit ou champ) dune classe.
Pour cela, il faut passer par une forme particulire du constructeur, et il faut que les proprits que
vous vouliez initialiser soient dclares comme publiques.
Imaginez par exemple la classe suivante :
publicclassUser
{
privatestring m_LastName;
publicstring LastName{
get { return m_LastName; }set { m_LastName = value; }
}
privatestring m_FirstName;
publicstring FirstName
{get { return m_FirstName; }
set { m_FirstName = value; }
}
privateint m_Age;
publicint Age{
get { return m_Age; }
set { m_Age = value; }}
public User(string firstname, string lastname, int age)
{this.m_FirstName = firstname;
this.m_LastName= lastname;
this.m_Age = age;
}
}
Que lon soit en C# 1 ou 2, pour instancier des objets de ce type, on faisait simplement :
-
8/14/2019 c# 3 Et Linq
13/51
P a g e | 13
User u1 = newUser();
u1.FirstName = "Thomas";
u1.LastName = "LEBRUN";
u1.Age = 24;
// Ou alors
User u2 = newUser("Thomas", "LEBRUN", 24);
La deuxime mthode est dj plus aise mais pourrait encore tre amliore, comme nous allons le
voir avec ce que permet C# 3 et les initialiseurs dobjets :
// Version C# 3var u3 = newUser { FirstName = "Thomas", LastName = "LEBRUN", Age = 24 };
Console.WriteLine("Je m'appelle {0} {1} et j'ai {2} ans", u3.FirstName,
u3.LastName, u3.Age);
Console.ReadLine();
Linstanciation des objets est alors plus simple et plus rapide, mais surtout grce elle, vous ntes
pas oblig de dclarer un constructeur spcifique dans votre classe. En effet, il vous suffit de dclarer
des proprits publiques et de faire appel leur nom, lors de l instanciation.
Vous ntes pas oblig de dclarer tous les champs, lors de linitialisation. Dans ce cas, des valeurs
par dfaut seront affectes aux champs non dclars.
C# 3 permet, une nouvelle fois, de faire la mme chose mais en travaillant avec des collections,comme vous le montre cet exemple :
// AvantList MyListOfInteger = newList();
MyListOfInteger.Add(1);
MyListOfInteger.Add(2);
MyListOfInteger.Add(3);MyListOfInteger.Add(4);
MyListOfInteger.Add(5);
// Avec C# 3
List MySecondListOfInteger = newList{6, 7, 8, 9, 10 };
foreach(int i in MySecondListOfInteger){
Console.WriteLine(i);
}
-
8/14/2019 c# 3 Et Linq
14/51
P a g e | 14
Les types anonymes
C# 3 propose la possibilit de crer des types anonymes et de retourner des instances de ce type, au
moyen du mot cl new.
var MyClass = new { PremierChamp = 1, SecondChamp = "Ma Chane", TroisiemeChamp =
newList(newint [] { 1, 2 , 3, 4, 5 }) };
Grce ce code, nous crons un objet possdant trois proprits, auxquelles nous pouvons tout
fait accder :
Console.WriteLine(MyClass.PremierChamp);Console.WriteLine(MyClass.SecondChamp);
foreach(int i in MyClass.TroisiemeChamp){
Console.WriteLine(i);
}
Le rsultat est, tout simplement:
Dans ce premier exemple, les noms des membres de la classe anonyme sont spcifis explicitement.
Mais vous pouvez tout fait omettre le nom de ces membres. Dans ce cas, le nom des membres
gnr est le mme que les membres utilis pour gnr lobjet. Voici un exemple :
var MySecondClass = new { MyClass.PremierChamp, MyClass.SecondChamp };
Console.WriteLine(MySecondClass.PremierChamp);
Console.WriteLine(MySecondClass.SecondChamp);
-
8/14/2019 c# 3 Et Linq
15/51
P a g e | 15
Le projet LINQ
LINQ
LINQ(Language Integrated Query) est un des nouveaux projets accompagnant C# 3.
Auparavant, les dveloppeurs taient amens utiliser deux ou plusieurs langages en mme temps
(C#, SQL, etc.). Malheureusement, cette approche avait des inconvnients :
Le compilateur ne vrifiait pas le contenu de ce qui tait entre double quotes Il ny avait pas de vrification de type sur les valeurs retournes Etc..
Nous allons donc voir, au travers de cette partie, quels sont les moyens mis en uvre par LINQ pour
palier ces inconvnients. A noter qu'ici nous parlerons de LINQ en faisant rfrence LINQ To
Objects.
Interroger une liste gnrique
Avant de rentrer trop dans les dtails, commenons par quelque chose de simple et voyons comment
LINQ peut nous permettre dinterroger une liste gnrique autrement dit, une liste dentiers, de
chane de caractres, de double, etc..
Voyons un exemple :
int [] tab = newint [] { 1, 2, 3, 4, 5, 6 };
IEnumerable paire = from number in tabwhere number % 2 == 0
select number;
foreach(int i in paire){
Console.WriteLine(i);
}
Cet exemple est relativement simple comprendre: nous dclarons un tableau dentier, puis nousutilisons LINQ pour interroger ce tableau et ne renvoyer que les nombres pairs.
-
8/14/2019 c# 3 Et Linq
16/51
P a g e | 16
Si vous prtez bien attention au code, vous remarquerez que LINQ utilise une syntaxe similaire celle
que lon retrouve dans le langage SQL : nous utilisons un from, un where et un select. Bien entendu,
il existe un nombre important doprateurs standards que nos verrons par la suite.
A la diffrence du SQL, DLINQ place linstruction fromavant linstruction select. Vous pourriez tout
fait trouver cela quelque peu surprenant mais sachez que ce choix a t fait par Microsoft aprs delongues discussions et que latout majeur de cette syntaxe repose dans le fait que de cette faon,
lIntelliSense de Visual Studio est compltement fonctionnelle.
Dans lexemple prcdent, nous interrogeons un tableau dentier: nous savons donc qu la sortie,
nous allons rcuprer un System.Collections.Generic.IEnumerable . Mais beaucoup de requtes
retournent un type complexe que vous ne connaissez pas forcment. Dans ce cas, le plus simple est
de passer par lune des fonctionnalits offertes par C# 3 : lutilisation de variables types
implicitement.
Ainsi, lexemple prcdent aurait trs bien pu scrire :
int [] tab = newint [] { 1, 2, 3, 4, 5, 6 };
var paire = from number in tabwhere number % 2 == 0
select number;
foreach(int i in paire)
{Console.WriteLine(i);
}
Et le rsultat aurait toujours t le mme :
Bien entendu, ce qui fonctionne avec les types simples fonctionne galement avec les types
complexes. Voyons par exemple comment appliquer ce que nous venons de voir une classe
nomme User (que nous avons dj utilise auparavant):
-
8/14/2019 c# 3 Et Linq
17/51
P a g e | 17
Commencez par crer une liste de Users que nous allons interroger par la suite :
var people = newList() {
newUser { LastName = "LEBRUN", FirstName = "Thomas", Age = 24 },
newUser { LastName = "LAMARCHE", FirstName = "Patrice", Age = 26 },newUser { LastName = "Inconnu" }
};
A prsent, nous allons utiliser la mme syntaxe que prcdemment pour interroger cette liste et faire
ressortir des rsultats en fonction des conditions que lon utilise :
var persons = from p in people
where p.Age > 25select p;
foreach(var person in persons)
{
Console.WriteLine("{0} {1} est ag de {2} ans: qu'il est vieux (it's a jokeof course :)", person.FirstName, person.LastName, person.Age);
}
var persons = from p in people
where p.Age > 20 && p.LastName.Length > 5select p;
Bien sur, une des fonctionnalits bien pratiques de LINQ est de pouvoir faire des JOIN :
var people = newList() {
newUser { LastName = "LEBRUN", FirstName = "Thomas", Age = 24 },newUser { LastName = "LAMARCHE", FirstName = "Patrice", Age = 26 },
newUser { LastName = "Inconnu" }};
var WygwamMembers = newList() {newUser { LastName = "RENARD", FirstName = "Grgory" },
newUser { LastName = "LAMARCHE", FirstName = "Patrice", Age = 26 },};
var Members = from p in people
select p;
var Wygwam = from p in WygwamMembers
select p;
var persons = from p in peoplejoin w in WygwamMembers
on (string)p.LastName equals (string)w.LastNameselect p;
-
8/14/2019 c# 3 Et Linq
18/51
P a g e | 18
foreach(var Member in Members)
{
Console.WriteLine("Membre de la 1re liste: {0} {1}", Member.FirstName,
Member.LastName);
}
foreach(var WygwamMember in Wygwam){
Console.WriteLine("Membre de Wygwam: {0} {1}", WygwamMember.FirstName,
WygwamMember.LastName);
}
foreach(var person in persons)
{Console.WriteLine("Membre de la 1re liste et de l'quipe Wygwam: {0} {1}",
person.FirstName, person.LastName);
}
Ici, on a ralis lquivalent dune requte JOIN sur deux tables. Cependant, nous somme pass par
deux listes (au lieu de deux tables). Nous avons ensuite, grce au mot cl on, spcifi sur quelle
proprit la jointure devrait tre fate. Finalement, le mot cl equals nous a permis dindiquer sur
quelle valeur cette jointure devrait tre fate.
Voici le rsultat du code prcdent :
Si on regarde un peu le code qui a t gnr (en utilisant Reflector), on peut apercevoir ceci:
IEnumerable enumerable1 = Sequence.Join(list1,(IEnumerable) list2, Program.9__CachedAnonymousMethodDelegated,
Program.9__CachedAnonymousMethodDelegatee,
Program.9__CachedAnonymousMethodDelegatef);
foreach (User user8 in enumerable1)
{Console.WriteLine("Membre de la 1\x00e8re liste et de l'\x00e9quipe Wygwam:
{0} {1}", user8.FirstName, user8.LastName);}
-
8/14/2019 c# 3 Et Linq
19/51
P a g e | 19
On voit donc que le JOIN est symbolis par la classe Sequence et plus particulirement par la
mthode Join de cette classe.
Les oprateurs standards
LINQ propose plus de 40 oprateurs diffrents. Nous n'allons donc pas tous les voir, mais seulement
nous attarder sur les plus importants/utiliss.
L'oprateur OfType
L'oprateur OfType est utilis pour rduire le nombre de rsultats dans une requte.
Attention, cela ne fonctionne que pour les valeurs de la requte dont le type est indiqu grce cet
oprateur.
Voici un exemple de code:
object [] values = { 1, "Tom", 'T', 12.5, 3, true, 20 };
var results = values.OfType();
foreach(int i in results){
Console.WriteLine(i);
}
Ici, seul les valeurs de type int seront retournes par le programme.
Les rsultats sont donc maintenant plus facilement manipulables/exploitables dans le reste de votre
application.
-
8/14/2019 c# 3 Et Linq
20/51
P a g e | 20
Les oprateurs Min, Max, Sum et Average (Moyenne)
Ces oprateurs, standards lorsque l'on travaille en SQL, sont maintenant disponibles avec LINQ.
Plutt que de faire de long discours, tant donn que leurs noms sont assez explicites, voici une
dmonstration:
int [] IntegerValues = { 0, 2, 5, 6, 7 };
int max = IntegerValues.Max();int min = IntegerValues.Min();
int sum = IntegerValues.Sum();
double average = IntegerValues.Average();
Console.WriteLine("Max: {0}", max);
Console.WriteLine("Min: {0}", min);Console.WriteLine("Sum: {0}", sum);Console.WriteLine("Moyenne: {0}", average);
Jusque l, rien de bien compliqu: on dclare un tableau d'entier et on appelle, sur ce tableau, les
mthodes adquates.
En interne, voici le code gnr par le compilateur:
int[] numArray2 = newint[] { 0, 2, 5, 6, 7 };
int num1 = Sequence.Max(numArray2);int num2 = Sequence.Min(numArray2);
int num3 = Sequence.Sum(numArray2);double num4 = Sequence.Average(numArray2);
Console.WriteLine("Max: {0}", num1);Console.WriteLine("Min: {0}", num2);
Console.WriteLine("Sum: {0}", num3);Console.WriteLine("Moyenne: {0}", num4);
Autrement dit, nous aurions tout aussi bien pu appeler les mthodes statiques de la classe Sequence
pour parvenir aux rsultats.
-
8/14/2019 c# 3 Et Linq
21/51
P a g e | 21
L'oprateur Select
Depuis un petit moment, nous utilisons l'oprateur Select mais sans trop vraiment savoir quoi il
sert et pourquoi il est utilis. Cette partie va donc tre l pour tenter de rtablir les choses.
L'oprateur Select est utilis pour crer la projection d'une squence (liste, tableau, etc.).
La collection rsultante de cette projection peur alors tre directement utilise comme source de
donnes d'un objet.
var values = newobject [] { 1, "Tom", 'T', 12.5, 3, true, 20 };
var val = from v in valuesselect v;
foreach(object o in val)
{Console.WriteLine(o.ToString());
}
Vous noterez une chose importante: le type retourn n'est jamais indiqu explicitement dans le
code: il est cr par le compilateur en se basant sur le type spcifi.
L'oprateur Where
L'oprateur Where va vous permettre de filtrer une squence de valeurs, tout comme on le fait en
SQL:
var values = newobject [] { 1, "Tom", 'T', 12.5, 3, true, 20 };
var val = from v in values
where v.ToString().Length >= 3
select v;
foreach(object o in val)
{Console.WriteLine(o.ToString());
}
-
8/14/2019 c# 3 Et Linq
22/51
-
8/14/2019 c# 3 Et Linq
23/51
P a g e | 23
var values = newint [] { 1, 2, 10, 23, 50 };
// Avec le Where
int count = values.Where(i => i >= 20).Count();
Console.WriteLine("Nombre total d'lments dans la liste: {0}", count);
C'est la fois rapide et trs puissant !
Les oprateurs ToArray et ToList
Les oprateurs ToArray et ToList sont utiliss pour convertir une squence en tableau typ ou liste.
Cela peut s'avrer trs pratique lorsque vous voulez lier une grille de donnes (GridView) une
squence, en utilisant la liaison de donnes ("DataBinding").
var values = newint [] { 1, 2, 10, 23, 50 };
int [] integerArray = values.ToArray();
ListintegerList = values.ToList();
foreach(int iArray in integerArray)
{Console.WriteLine(iArray);
}
foreach(int iList in integerList)
{Console.WriteLine(iList);
}
Aprs avoir couvert un aperu des possibilits offertes par LINQ, intressons nous un sous-
ensemble qui permet de manipuler, plus aisment, les bases de donnes et de faire du mapping
objet-relationnel.
-
8/14/2019 c# 3 Et Linq
24/51
P a g e | 24
DLINQ
DLINQ est une sous-partie de LINQ qui se concentre sur tout ce qui traite de l'accs aux donnes avec
LINQ.
En utilisant le terme DLINQ, je dois admettre que je commets une erreur de langage. En effet,
Microsoft a annonc rcemment que DLINQ avait t renomm en:
LINQ to SQL, anciennement connu sous le nom de DLINQ et qui sera une technologie demapping objet-relationnel simple
LINQ to Entities, qui sera la base du nouveau Framework dEntit dADO.NET. Il s'agit d'unetechnologie de mapping objet-relationnel plus complexe.
A titre d'information, sachez que cet article ne traitera que de LINQ for SQL.
LINQ for SQL
Crer votre premire couche d'accs aux donnes
LINQ for SQL reprsente une technologie de mapping objet relationnel la fois simple mais efficace.
Je ne vais pas traiter ici du mapping objet mais simplement vous dmontrer comment il est possible,
avec LINQ for SQL, de manipuler facilement une base de donnes.
Pour cet article, j'ai travaill avec SQL Server 2005 (et la la base de donnes AdventureWorks) mais
sachez que cela fonctionne parfaitement avec SQL Server 2000. A terme, il sera mme possible
d'interagir avec d'autre systme de bases de donnes (Oracle, etc..)
Commencer par crer, dans Visual Studio 2005, un nouveau projet de type "LINQ Preview" et dans ce
projet, ajouter une classe entit (que vous nommerez Employees) et qui servira mapper la table
Employees.
Pour cela, utiliser le code suivant:
-
8/14/2019 c# 3 Et Linq
25/51
P a g e | 25
using System.Data.DLinq;
[Table(Name="Employees")]
publicclassEmployees
{privateint m_EmployeeId;
[Column(Id=true)]
publicint EmployeeId
{
get
{return m_EmployeeId;
}set
{
m_EmployeeId = value;
}
}
privatestring m_EmployeeLastName;
[Column(Storage="m_EmployeeLastName")]
publicstring LastName
{
get{
return m_EmployeeLastName;
}set
{
m_EmployeeLastName = value;
}}
}
L'attribut Table sert mapper une classe une table de la base de donnes. L'attribut Column,
quand lui, est utilis pour mapper les champs de votre classe aux colonnes de votre table.
Pour indiquer qu'une colonne est la cl primaire d'une table, il vous faut tout simplement utiliser le
paramtre Id et le positionner true.
Les champs peuvent tre mapps la base de donnes mais la plupart du temps, il est conseilld'utiliser les proprits publiques. Lorsque vos dclarez une proprit publique, vous devez indiquer
le champ de stockage correspondant, au moyen du paramtre Storage de l'attribut Column.
Vous venez donc d'crire votre premire classe de mapping avec DLINQ ! Voyons alors comment
utiliser cette classe dans votre application.
-
8/14/2019 c# 3 Et Linq
26/51
-
8/14/2019 c# 3 Et Linq
27/51
P a g e | 27
Expliquons un peu plus en dtails le code que nous venons d'crire:
Nous commenons par crer un DataContext, qui va tre notre interface avec la base de donnes.
Nous pouvons lui passer en paramtre:
Une chane de connexion Un fichier de base de donnes (fichier MDF) Une connexion
Ensuite, nous activons le Log afin de pourvoir visualiser les requtes SQL qui seront gnres puis
excutes sur la base. Cette tape n'est en rien obligatoire et n'est utile que lorsque vous fates du
dbogage.
Ensuite, nous rcuprons le contenu de la table Employees. Cette table ne contient pas,physiquement, toutes les lignes de la table mais travaille comme un proxy pour les requtes
fortement types.
Pour finir, nous effectuons une requte pour rcuprer une liste d'employes, que nous afficherons
par la suite.
Voyons prsent comment faire lorsque nous travaillons avec des bases de donnes plus complexes,
qui possdent, par exemple, des relations entre des tables. C'est en effet un des cas les plus courants
et il serait dommage de ne pas le voir.
-
8/14/2019 c# 3 Et Linq
28/51
-
8/14/2019 c# 3 Et Linq
29/51
P a g e | 29
Le code ici prsent est peut-tre long, mais il s'avre simple comprendre.
Les attributs sont utiliss pour reprsenter le type des champs dans la base. On peut, par exemple,
affirmer que le champ OrderID est de type entier, qu'il est non nul et qu'il est auto-incrment. Bref,
tout cela est assez logique.
A noter que pour la proprit OrderID, nous n'avons pas besoin de spcifier de setter car AutoGen
est positionn true (Vrai).
Pour reprsenter une relation un un (one to one) ou un plusieurs (one to many), DLINQ vous
permet d'utiliser les types EntityRefet EntitySet. L'attribut Association est utilis pour mapper la
relation.
En crant l'association ci-dessus, vous serez mme d'utiliser la proprit Order.Employee pour
accder directement l'objet Employee appropri.
Le type EntityRef est utilis dans la classe Orders car il n'y a qu'un seul employ associ unecommande donne.
Ds lors, vous pouvez accder un employ particulier en passant par les commandes. Mais si vous
souhaitez faire l'inverse (accder aux commandes depuis les employes), vous devez rajouter la
relation adquate dans la classe Employees:
privateEntitySetm_Orders;
public Employees(){
this.m_Orders = newEntitySet();
}
[Association(Storage="m_Orders", OtherKey="EmployeeId")]publicEntitySetOrdersForEmployee
{get { returnthis.m_Orders; }
set { this.m_Orders.Assign(value); }
}
Notez que dans ce cas l, nous utilisons un type EntitySet car la relation entre Employees et Orders
est de un plusieurs (one to many).
Ds lors, vous pouvez accder aux objets de type Orders depuis les objets de type Employees, et vice-
versa:
-
8/14/2019 c# 3 Et Linq
30/51
P a g e | 30
var EmployeeList = from e in employees
where e.OrdersForEmployee.Any()
select e;
foreach(Employees employee in EmployeeList){
Console.WriteLine("EmployeeId: {0}\t Employee LastName: {1}\t Quantity:{2}", employee.EmployeeId, employee.LastName, employee.OrdersForEmployee.Count);
}
Jusqu' maintenant, nous avons utilis un DataContext classique. Nous allons voir comment nous
pouvons typer cet objet DataContext, puis travailler avec.
Travailler avec l'objet DataContext fortement typ
Avant votre classe Employees, ajoutez le code suivant:
publicclassNorthwind : DataContext
{publicTableEmployeesTable;
publicTableOrdersTable;
public Northwind(string connection) : base(connection) {}}
Nous crons une classe Northwind (du nom de notre base de donnes) qui hrite de la classe
DataContext.
Dans cette classe, nous rajoutons la dclaration des tables Employees et Orders que nous avons
utilises prcdemment. Puis dans le Main de notre programme, nous utilisons cette classe la place
du DataContext classique:
Northwind db = newNorthwind(@"Data Source=.\SQL2005;Initial
Catalog=Northwind;User Id=login;Password=password;");
var EmployeeList = from e in db.EmployeesTablewhere e.EmployeeId > 5
select e;
foreach(Employees employee in EmployeeList)
{
Console.WriteLine("EmployeeId: {0}\t Employee LastName: {1}",employee.EmployeeId, employee.LastName);
}
-
8/14/2019 c# 3 Et Linq
31/51
P a g e | 31
A prsent, vous n'avez plus besoin de faire appel GetTable pour accder aux tables de votre
base de donnes: en passant par leur nom, le travail est fait de la mme manire.
Comme vous pouvez le voir, cette utilisation d'un DataContext fortement typ est trs pratique maispeut s'avrer trs longue mettre en place dans le cas o votre base de donnes comporte de
nombreuses tables.
Pour pallier ce problme, vous avez votre disposition un outil, SqlMetal.exe, qui vous permet de
gnrer, automatiquement, votre modle objet.
Gnrer votre modle objet avec SqlMetal:
SqlMetal.exe est un outil de gnration de code qui va vous permettre de gnrer votre modle
objet sans que vous ayez besoin d'crire vous-mme une ligne de code.
Pour lancer SqlMetal, cliquez sur "Dmarrer" => "Programmes" => "Microsoft Visual Studio 2005"
=> "Visual Studio Tools" => Visual Studio Command Prompt".
Commencer par changer de rpertoire courant pour vous positionner dans le rpertoire de votre
projet puis saisissez la ligne suivante pour lancer la gnration de votre modle objet. Attention, il
existe un nombre important de paramtre donc vous de regarder la documentation/l'aide si vousvoulez en avoir plus sur une option prcise:
"c:\Program Files\LINQ Preview\bin\SqlMetal.exe" /server:.\SQL2005
/database:Northwind /pluralize /code:Northwind.cs /user:login /password:password
Une fois le fichier gnr, il ne vous reste plus qu' l'ajouter dans votre projet. Pour celui, fates un
clic droit sur votre projet, puis choisissez "Existing Item" et slectionnez votre fichier (Northwind.cs).
L'utilisation de ce fichier auto-gnr est la mme que lorsque vous avez utilis le DataContext
fortement typ:
Northwind db = newNorthwind(@"Data Source=.\SQL2005;InitialCatalog=Northwind;User Id=login;Password=password;");
var customers = from c in db.Customers
select c;foreach(Customer c in customers)
{Console.WriteLine("CustomerID: {0}\t CustomerName: {1}", c.CustomerID,
c.ContactName);}
-
8/14/2019 c# 3 Et Linq
32/51
P a g e | 32
Si vous voulez utiliser des requtes un peu plus complexes, alors rien ne vous en empche:
var EmployeeList = (
from e in db.Employees
from c in db.Customerswhere c.City == e.City
selectnew { ID = e.EmployeeID, Name =String.Concat(e.LastName, " ", e.FirstName) }
).Distinct();
foreach(var employee in EmployeeList)
{Console.WriteLine("ID: {0}\t Name: {1}", employee.ID, employee.Name);
}
Si on regarde la requte SQL qui est gnre, on peut voir que ce n'est pas quelque chose deforcment ais crire pour quelqu'un qui n'est pas administrateur de base de donnes:
SELECT DISTINCT [t2].[EmployeeID] AS [ID], [t2].[value] AS [Name]
FROM (SELECT [t0].[EmployeeID], ([t0].[LastName] + @p0) + [t0].[FirstName] AS
[value], [t1].[City], [t0].[City] AS [City2]
FROM [Employees] AS [t0], [Customers] AS [t1]
) AS [t2]
WHERE [t2].[City] = [t2].[City2]
Modifier la base de donnes
Vous pouvez, grce LINQ, manipuler la base de donnes. Nous allons alors voir comment faire pour
parvenir nos fins.
Ajouter une entit
Pour ajouter une entit, rien de plus simple: il vous suffit de crer l'entit et de l'ajouter la table de
votre base de donnes.
-
8/14/2019 c# 3 Et Linq
33/51
-
8/14/2019 c# 3 Et Linq
34/51
P a g e | 34
Voici un petit exemple du rsultat:
Supprimer une entit
Pour supprimer une entit, l encore, pas de mystres: un simple appel la mthode Remove et le
tour est jou:
var my = (
from c in db.Customers
where c.CustomerID == "THLEB"
select c).First();
// On supprime la ligne de la tabledb.Customers.Remove((Customer)my);
// On valide la transaction
db.SubmitChanges();
-
8/14/2019 c# 3 Et Linq
35/51
P a g e | 35
Le designer DLINQ
Crer l'objet DLinq avec le designer
Tout ce que nous avons fait jusqu' maintenant est entirement fonctionnel, sans problmes
particulier.
Mais en bon dveloppeur, vous avez sans doute remarqu que gnrer un DataContext typ peut
vite s'avrer laborieux et lourd de travail.
Une chose pourrait vous manquer, surtout si vous avez l'habitude de travailler avec la souris: le
glisser/dposer.
En effet, imaginiez que vous soyez en mesure de faire un glisser/dposer des tables d'une base de
donnes: vous auriez alors la possibilit de raliser ce DataContext de faon beaucoup plus rapide etnaturelle.
Et bien sachez que cette possibilit existe ! En effet, DLINQ intgre un designer qui vous permet, par
simple glisser/dposer depuis Visual Studio, de gnrer un DataContext fortement typ, et de
travailler avec par la suite.
Pour utiliser ce designer, il vous suffit de rajouter, votre projet, un lment de type "DLinq
Objects". Pour cela, fates un clic droit sur le nom de votre projet et choisissez "Add New Item" =>
"DLinqObjects" :
Ensuite, il ne vous reste plus qu' faire une glisser/dposer des tables de votre base de donnes qui
vous intresse, tout cela depuis votre explorateur de serveurs.
-
8/14/2019 c# 3 Et Linq
36/51
P a g e | 36
Dans notre cas, nous allons glisser/dposer les table: Customer, Order, Order Details, Product et
Employee.
Voici ce que vous devez obtenir:
Et si l'on regarde le code qui a t gnr, on s'aperoit qu'il ressemble fort celui que l'on sait
maintenant crire nous mme:
publicpartialclassNorthwindDataContext : System.Data.DLinq.DataContext
{public System.Data.DLinq.TableCustomers;
public System.Data.DLinq.TableOrders;
public System.Data.DLinq.TableOrder_Details;public System.Data.DLinq.TableProducts;
public System.Data.DLinq.TableEmployees;
-
8/14/2019 c# 3 Et Linq
37/51
P a g e | 37
Utiliser l'objet DLinq
Pour utiliser cet objet nouvellement cr, vous pouvez par exemple ajouter une nouvelle source de
donnes qui aura comme origine cet objet.
Pour cela, dans le menu, cliquez sur "Data" puis choisissez "Add new Data Source". Sur l'cran
suivant, slectionner "Object" comme source de vous donnes puis naviguer jusqu' l'objet de votre
choix, par exemple Customer:
A prsent, vous pouvez tout simplement utiliser cette nouvelle source de donnes. Pour cela, vous
pouvez essayez, depuis la fentre "Data Source", de faire un glisser/dposer de l'objet Customer sur
votre formulaire principal. Comme son habitude, Visual Studio 2005 vous gnrera tout le code (ou
tout du moins une trs trs grande partie du code) ainsi que de l'interface graphique:
-
8/14/2019 c# 3 Et Linq
38/51
P a g e | 38
Ensuite, il ne reste plus qu' utiliser le DataContext typ que vous avez cr tout l'heure pour
remplir cette grille de donnes.
Pour cela, ajoutez la dclaration suivante dans votre code:
privateNorthwindDataContext db = newNorthwindDataContext();
Et ensuite, vous devez simplement lier la source de donnes de votre grille votre DataContext:
privatevoid Form1_Load(object sender, EventArgs e){
this.customerBindingSource.DataSource = this.db.Customers.ToBindingList();
}
A l'excution, on s'aperoit que tout fonctionne bien correctement:
Etant donn qu'il y a une relation entre Customer et Orders (celle-ci est reprsente par une
association, sur le diagramme de classe), nous avons donc une proprit Orders, au sein de la classe
Customer, qui contient une collection d'objet de type Orders.
Si, depuis la fentre "Data Source", vous fates un glisser/dposer de cette proprit sur votre
formulaire, vous vous rendrez compte que les informations sur les clients et sur les commandes sont
affiches, et que les commandes sont lies au client slectionn:
-
8/14/2019 c# 3 Et Linq
39/51
P a g e | 39
Designer DLinq et requtes DLinq
Vous avez galement la possibilit d'utiliser des requtes DLinq avec le DataContext que le designer
vous a gnr.
Voici un petit exemple:
privatevoid btQuery_Click(object sender, EventArgs e){
var results = from customers inthis.db.Customers
where customers.City == this.tbCity.Textselect customers;
this.customerBindingSource.DataSource = results.ToBindingList();
}
Ici, nous effectuons une requte DLinq qui va chercher une liste de client en fonction de leur ville.
Ensuite, nous lions notre grille de clients aux rsultats de cette requte:
-
8/14/2019 c# 3 Et Linq
40/51
P a g e | 40
Filtrer les rsultats dynamiquement
Une des possibilits qui vous est offerte est de pouvoir, dynamiquement, filtrer les rsultats.
Pour cela, un peu plus de code va tre ncessaire. En effet, vous allez devoir crer un filtre en vous
basant sur sur une expression lambda:
privatevoid btFilter_Click(object sender, EventArgs e)
{
var p = Expression.Parameter(typeof(Customer), "");var filter = (Expression)QueryExpression.Lambda(this.tbFilter.Text, p);
this.customerDataGridView.DataSource =this.db.Customers.Where(filter).ToList();
}
Si on excute, on s'aperoit bien qu'un clic sur le bouton "Filtrer" filtre bien les rsultats en fonction
de notre critre:
-
8/14/2019 c# 3 Et Linq
41/51
P a g e | 41
Une autre faon de faire aurait pu tre:
privatevoid btFilter_Click(object sender, EventArgs e)
{
var p = Expression.Parameter(typeof(Customer), "c");var filter = (Expression)QueryExpression.Lambda(this.tbFilter.Text, p);
this.customerDataGridView.DataSource =
this.db.Customers.Where(filter).ToList();
}
La diffrence avec la premire technique se situe au niveau du deuxime argument de la mthode
Parameter: ici, on spcifie une valeur ce qui nous oblige, lorsque l'on applique le filtre, utiliser cette
valeur:
Avant, pour construire notre arbre d'expression et appliquer un filtre, nous utilisions:
City = "London"
Maintenant, on utilise
c.City = "London"
-
8/14/2019 c# 3 Et Linq
42/51
P a g e | 42
XLINQ
LINQ propose galement des API ddies l'accs/manipulation de sources XML.
Ces API sont regroupes dans ce que l'on appelle XLINQ(.NET Language Integrated Query for XML
Data).
XLINQ possde les avantages des oprateurs de requtes standards et ajoute des extensions ddies
XML. D'un point de vue XML, XLINQ fournit la puissance des requtes et des transformations de
XQuery et de XPath, le tout intgr dans .NET.
Voici, titre d'information, une image vous prsentant les principales classes de XLINQ:
XAttributeXNode
XComment XContainer
XDeclaration
XDocument
XDocumentType
XElement
XName
XProcessingInstructionXText
XNamespace XStreamingElement
Maintenant que nous connaissons la structure hirarchique des classes de XLINQ, voyons comment
nous pouvons travailler avec et produire des choses assez sympathiques.
Charger un document XML
Pour charger un document XML, avec XLINQ, vous avez 2 mthodes.
La premire est d'appeler la mthode Parse de la classe XElement et de lui passer, en paramtre, le
contenu de votre XML:
-
8/14/2019 c# 3 Et Linq
43/51
P a g e | 43
XElement contacts = XElement.Parse(
@"
Patrick Hines
206-555-0144425-555-0145
123 Main St
Mercer Island
WA
68042
10
"
);
Ceci est valable dans le cas o vous rcuprer un flux XML que vous voulez lire par exemple.
Une autre possibilit, si vous avez directement accs au fichier XML, est d'appeler la mthode Load:
XElement contactsFromFile = XElement.Load(@"c:\myContactList.xml");
Vous avez moins de code crire mais vous devez obligatoirement avoir accs au fichier pour
appliquer cette mthode.
Crer des lments XML
Pour crer des lments XML, avec XLINQ, vous devez faire appel ce que l'on appelle la
"construction fonctionnelle".
Il s'agit d'une technique qui vous permet de crer tout (ou une simple partie) de votre arbre XML, en
une seule tape:
XElement contacts =
newXElement("contacts",
newXElement("contact",
newXElement("name", "Patrick Hines"),newXElement("phone", "206-555-0144"),
newXElement("address",newXElement("street1", "123 Main St"),
newXElement("city", "Mercer Island")
))
);
-
8/14/2019 c# 3 Et Linq
44/51
-
8/14/2019 c# 3 Et Linq
45/51
P a g e | 45
Les lments XML tant importants dans beaucoup de scnarios, vous pouvez faire appel la
mthode Elements() qui est en fait un raccourci vers Nodes.OfType() .
Si vous avez besoin de vous rfrer un lment particulier, il vous suffit d'utiliser la mthodeElement et de lui passer en paramtre le nom de l'lment qui vous intresse. De cette faon, vous
rcuprerez en retour un XElement. S'il y en a plusieurs du mme nom, vous rcuprerez le premier:
XElement name = contacts.Element("name");string NameValue = (string)contacts.Element("name");
Console.WriteLine(NameValue);
Manipuler un XML
Si vous avez en de manipuler un XML (ajouter/supprimer/modifier des enregistrements), alors XLINQ
vous permet de le faire facilement.
Ajouter un lment
Pour ajouter un lment, il n'y a rien de bien compliqu: vous devez juste dclarer vous XElement et
l'ajouter l o vous le souhaitez.
La plupart du temps, on l'ajoute sur un XElement dj existant:
XElement mobilephone = newXElement("mobilephone", "206-333-4546");
contacts.Add(mobilephone);
Il existe d'autres "variantes" de la mthode Add(). Vous avez par exemple la mthode AddFirst() qui
vous sert ajouter votre lment au dbut de votre XML, ainsi que les mthodes AddAfterThis et
AddBeforeThis, qui vous seront utiles si vous souhaitez ajouter un lment avant ou aprs un
lment particulier.
-
8/14/2019 c# 3 Et Linq
46/51
P a g e | 46
Supprimer un lment
Pour supprimer un lment, vous devez dj avoir trouv la rponse: il vous suffit d'appeler la
mthode Remove():
contacts.Element("mobilephone").Remove();
C'est simple, rapide , efficace et entirement fonctionnel.
Une chose importante noter, c'est que Remove() fonctionne aussi sur les IEnumerable donc vous
pouvez tout fait appeler cette mthode sur une collection, par exemple la collection d'Elements:
contacts.Elements("phone").Remove();
La dernire chose savoir: si vous voulez supprimer le contenu d'un lment, et non pas l'lment
en lui-mme, il vous suffit d'appeler la mthode RemoveContent():
contacts.Element("mobilephone").RemoveContent();
Modifier un lment
XLINQ met votre disposition deux mthodes pour mettre jour un lment:
ReplaceContent, qui agit sur l'lment mme SetElement, qui travaille depuis l'lment parent
Pour bien comprendre la diffrence entre ces deux mthodes, regardons des exemples:
contacts.Element("mobilephone").ReplaceContent("0123456789");
c ontacts.SetElement("mobilephone", "0123456789");
-
8/14/2019 c# 3 Et Linq
47/51
P a g e | 47
Dans le premier bout de code, nous nous positionnons sur le nud qui nous intresse puis dessus,
nous appelons la mthode ReplaceContent.
Dans le deuxime cas, nous nous plaons sur l'lment parent, puis nous appelons SetElement pour
dfinir la valeur que doit prendre l'lment dont nous passons le nom en paramtre.
Ainsi, en fonction de la position laquelle vous vous trouvez, dans votre XML, vous pouvez toujours
modifier la valeur d'un nud.
Il faut savoir que si vous passer la valeur null comme second paramtre de la mthode SetElement,
l'lment en question sera supprim.
Travailler avec les attributs
Elments non ngligeables lorsque l'on travaille avec des documents XML, les attributs peuvent
galement tre manipuls avec XLINQ, au moyen de classes et mthodes spcialises.
C'est ce que nous allons voir dans cette partie.
Ajouter des attributs
La technique pour ajouter un XAttribute est trs similaire celle employe pour ajouter un XElement:
XElement contacts =
newXElement("contacts",newXElement("contact",
newXElement("name", "Patrick Hines"),
newXElement("phone",
newXAttribute("type", "home"),"206-555-0144"),
newXElement("phone",
newXAttribute("type", "pro"),"206-333-4567"),
newXElement("address",
newXElement("street1", "123 Main St"),
newXElement("city", "Mercer Island")
))
);
-
8/14/2019 c# 3 Et Linq
48/51
P a g e | 48
Modifier/Supprimer/Mettre jour des attributs
De la mme manire que vous avez utilis SetElement pour mettre jour, supprimer ou ajouter des
lments, vous pouvez faire la mme chose avec la mthode SetAttribute():
Si l'attribut existe, il sera mis jour Si l'attribut n'existe pas, il sera cr Si la valeur du deuxime paramtre de la mthode SetAttribute est null, l'attribut sera
supprim
De mme, pour supprimer un attribut, vous pouvez l encore faire appel la mthode Remove():
contacts2.Element("phone").Attribute("type").Remove();
Accder aux attributs
Pour accder un attribut, vous devez simplement utiliser la mthode Attribute, de la classe
XElement, qui prend en paramtre le nom de l'attribut atteindre/auquel vous souhaitez accder:
foreach(var p in contacts2.Elements("phone"))
{
if((string)p.Attribute("type") == "home")
{
Console.WriteLine("Tel perso: {0}", (string)p);}
}
Ainsi, on voit qu'accder aux attributs est chose relativement aise, puissant et fonctionne sur le
mme modle que la technique pour accder aux XElement.
-
8/14/2019 c# 3 Et Linq
49/51
P a g e | 49
Produire du XML
Pour produire du XML, vous pouvez utiliser l'une des nombreuses surcharges de la mthode Save()
des type XElement et XDocument.
Vous pouvez sauvegardez votre XML dans un fichier, un TextWriter ou un XmlWriter:
contacts2.Save("C:\Contacts.xml");
Requter du XML avec XLINQ
Les techniques de requtage que nous avons vues prcdemment peuvent tout fait tre appliques
XLINQ pour requter du XML.
Voyons un exemple dans lequel nous interrogeons une liste de contacts au format XML:
var result2 = from c in contacts.Elements("contact")select c.Element("name");
foreach(XElement name in result2)
{
Console.WriteLine(name.Value);
}
Si on regarde le rsultat, on obtient bien la liste des noms des contacts de notre XML:
-
8/14/2019 c# 3 Et Linq
50/51
P a g e | 50
Conclusions
Au travers de cet article, vous avez dcouvert C# 3 ainsi que LINQ For SQL.
Vous avez ainsi pu dcouvrir les possibilits techniques qui taient offertes et mises disposition desdveloppeurs.
Bien sur, il y aurait beaucoup plus de choses dire: nous n'avons que survol le sujet, mais nous
avons dj un petit bagage technique.
Bien que toujours en version Beta, je ne saurais que trop vous recommander de commencer jeter
un il et vous documenter sur ce que vous avez vu ici: en effet, il s'agit l de ce qui sera disponibledemain, et afin de bien prparer l'avenir, le mieux est de commencer le plus tt possible.
-
8/14/2019 c# 3 Et Linq
51/51
P a g e | 51
Remerciements
Je tiens remercier:
Mitsuru Furuta Fabrice Marguerie Jean-Baptiste Evain
Pour la relecture et les conseils techniques qu'ils ont pu apporter cet article.
http://blogs.microsoft.fr/mitsufuhttp://blogs.microsoft.fr/mitsufuhttp://weblogs.asp.net/fmarguerie/http://weblogs.asp.net/fmarguerie/http://evain.net/blog/http://evain.net/blog/http://evain.net/blog/http://weblogs.asp.net/fmarguerie/http://blogs.microsoft.fr/mitsufu