c# 3 et linq

Upload: facilus93

Post on 30-May-2018

220 views

Category:

Documents


0 download

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