Procédure pas à pas : écriture de requêtes dans Visual Basic

Cette procédure montre comment vous pouvez utiliser les fonctionnalités du langage Visual Basic pour écrire des expressions de requête LINQ (Language-Integrated Query). La procédure pas à pas montre comment créer des requêtes sur une liste d’objets Student, comment exécuter les requêtes et comment les modifier. Les requêtes incorporent plusieurs fonctionnalités, notamment les initialiseurs d’objets, l’inférence de type de variable locale et les types anonymes.

Une fois cette procédure pas à pas terminée, vous serez prêt à passer aux exemples et à la documentation du fournisseur LINQ spécifique qui vous intéresse. Les fournisseurs LINQ incluent LINQ to SQL, LINQ to DataSet et LINQ to XML.

Créer un projet

Pour créer un projet d’application console

  1. Démarrez Visual Studio.

  2. Dans le menu Fichier , pointez sur Nouveau, puis cliquez sur Projet.

  3. Dans la liste Modèles installés, cliquez sur Visual Basic.

  4. Dans la liste des types de projets, cliquez sur l’application Console. Dans la zone Nom, attribuez un nom pour le projet, puis cliquez sur OK.

    Un projet est créé. Par défaut, il contient une référence à System.Core.dll. En outre, la liste Espaces de noms importés sur la page Références, Concepteur de projet (Visual Basic) inclut l’espace de noms System.Linq.

  5. Dans la page Compiler, Concepteur de projets (Visual Basic), vérifiez que Option infer est définie sur Activé.

Ajouter une source de données en mémoire

La source de données pour les requêtes de cette procédure pas à pas est une liste d’objets Student. Chaque objet Student contient un prénom, un nom, une année de classe et un classement académique pour le corps de l’étudiant.

Pour ajouter la source de données

  • Définissez une classe Student et créez une liste d’instances pour la classe.

    Important

    Le code nécessaire pour définir la classe Student et créer la liste utilisée dans les exemples de la procédure pas à pas est fourni sur le Guide pratique : créer une liste d’éléments. Vous pouvez le copier et le coller dans votre projet. Ce nouveau code remplace le code qui s’est affiché lorsque vous avez créé le projet.

Pour ajouter un nouvel étudiant à la liste des étudiants

  • Suivez le modèle de la méthode getStudents pour ajouter une autre instance de la classe Student à la liste. L’ajout de l’étudiant vous présente les initialiseurs d’objets. Pour plus d’informations, consultez Initialiseurs d’objets : types nommés et anonymes.

Créer une requête

Une fois exécutée, la requête ajoutée dans cette section génère une liste des étudiants dont le classement académique les place dans les dix premiers. Étant donné que la requête sélectionne à chaque fois l’objet complet Student, le type du résultat de la requête est IEnumerable(Of Student). Toutefois, le type de la requête n’est généralement pas spécifié dans les définitions de requête. Au lieu de cela, le compilateur utilise l’inférence de type de variable locale pour déterminer le type. Pour plus d’informations, consultez Inférence de type de variable locale. La variable de portée de la requête, currentStudent, sert de référence à chaque instance Student dans la source, students, en fournissant l’accès aux propriétés de chaque objet dans students.

Pour créer une requête simple

  1. Recherchez l’emplacement dans la méthode Main du projet marqué comme suit :

    ' ****Paste query and query execution code from the walkthrough,
    ' ****or any code of your own, here in Main.
    

    Copiez puis collez le code suivant.

    Dim studentQuery = From currentStudent In students
                       Where currentStudent.Rank <= 10
                       Select currentStudent
    
  2. Placez le pointeur de la souris sur studentQuery dans votre code pour vérifier que le type attribué par le compilateur est IEnumerable(Of Student).

Exécuter la requête

La variable studentQuery contient la définition de la requête, et non les résultats de l’exécution de la requête. Un mécanisme classique d’exécution d’une requête est une boucle For Each. Chaque élément de la séquence renvoyée est accessible via la variable d’itération dans la boucle. Pour plus d’informations sur l’exécution des requêtes, consultez Écriture de votre première requête LINQ.

Pour exécuter la requête

  1. Ajoutez la boucle suivante For Each sous la requête dans votre projet.

    For Each studentRecord In studentQuery
        Console.WriteLine(studentRecord.Last & ", " & studentRecord.First)
    Next
    
  2. Placez le pointeur de la souris sur la variable de contrôle de boucle studentRecord pour consulter son type de données. Le type de studentRecord est déduit comme étant Student, car studentQuery renvoie une collection d’instances Student.

  3. Générez et exécutez l’application en appuyant sur Ctrl + F5. Notez les résultats dans la fenêtre de console.

Modifier la requête

Il est plus facile d’analyser les résultats de la requête s’ils se trouvent dans un ordre précis. Vous pouvez trier la séquence renvoyée en fonction de n’importe quel champ disponible.

Pour classer les résultats

  1. Ajoutez la clause suivante Order By entre l’instruction Where et l’instruction de la requête Select. La clause Order By trie les résultats par ordre alphabétique de A à Z, en fonction du nom de chaque étudiant.

    Order By currentStudent.Last Ascending
    
  2. Pour classer par nom, puis par prénom, ajoutez les deux champs à la requête :

    Order By currentStudent.Last Ascending, currentStudent.First Ascending
    

    Vous pouvez également spécifier Descending pour trier de Z à A.

  3. Générez et exécutez l’application en appuyant sur Ctrl + F5. Notez les résultats dans la fenêtre de console.

Pour introduire un identificateur local

  1. Ajoutez le code dans cette section pour introduire un identificateur local dans l’expression de requête. L’identificateur local contiendra un résultat intermédiaire. Dans l’exemple suivant, name est un identificateur qui contient une concaténation des prénoms et des noms des étudiants. Un identificateur local peut être utilisé à des fins pratiques ou il peut améliorer les performances en stockant les résultats d’une expression qui serait autrement calculée plusieurs fois.

    Dim studentQuery2 =
            From currentStudent In students
            Let name = currentStudent.Last & ", " & currentStudent.First
            Where currentStudent.Year = "Senior" And currentStudent.Rank <= 10
            Order By name Ascending
            Select currentStudent
    
    ' If you see too many results, comment out the previous
    ' For Each loop.
    For Each studentRecord In studentQuery2
        Console.WriteLine(studentRecord.Last & ", " & studentRecord.First)
    Next
    
  2. Générez et exécutez l’application en appuyant sur Ctrl + F5. Notez les résultats dans la fenêtre de console.

Pour projeter un champ dans la clause Select

  1. Ajoutez la requête et la boucle For Each de cette section pour créer une requête qui produit une séquence dont les éléments diffèrent des éléments de la source. Dans l’exemple suivant, la source est une collection d’objets Student, mais un seul membre de chaque objet est renvoyé : le prénom des étudiants dont le nom est Garcia. Étant donné que currentStudent.First est une chaîne, le type de données de la séquence renvoyée par studentQuery3 est IEnumerable(Of String), une séquence de chaînes. Comme dans les exemples précédents, l’attribution d’un type de données pour studentQuery3 est laissée au compilateur, qui utilise l’inférence de type local.

    Dim studentQuery3 = From currentStudent In students
                        Where currentStudent.Last = "Garcia"
                        Select currentStudent.First
    
    ' If you see too many results, comment out the previous
    ' For Each loops.
    For Each studentRecord In studentQuery3
        Console.WriteLine(studentRecord)
    Next
    
  2. Placez le pointeur de la souris sur studentQuery3 dans votre code pour vérifier que le type attribué est IEnumerable(Of String).

  3. Générez et exécutez l’application en appuyant sur Ctrl + F5. Notez les résultats dans la fenêtre de console.

Pour créer un type anonyme dans la clause Select

  1. Ajoutez le code de cette section pour voir comment les types anonymes sont utilisés dans les requêtes. Vous les utilisez dans les requêtes lorsque vous souhaitez renvoyer plusieurs champs de la source de données plutôt que d’effectuer des enregistrements complets (enregistrements currentStudent dans les exemples précédents) ou des champs uniques (First dans la section précédente). Au lieu de définir un nouveau type nommé qui contient les champs que vous souhaitez inclure dans le résultat, vous spécifiez les champs dans la clause Select et le compilateur crée un type anonyme avec ces champs comme propriétés. Pour plus d’informations, consultez Types anonymes.

    L’exemple suivant crée une requête qui renvoie le nom et le rang des étudiants plus âgés dont le classement académique est compris entre 1 et 10, par ordre de classement académique. Dans cet exemple, le type de studentQuery4 doit être déduit, car la clause Select renvoie une instance d’un type anonyme et un type anonyme n’a pas de nom utilisable.

    Dim studentQuery4 =
            From currentStudent In students
            Where currentStudent.Year = "Senior" And currentStudent.Rank <= 10
            Order By currentStudent.Rank Ascending
            Select currentStudent.First, currentStudent.Last, currentStudent.Rank
    
    ' If you see too many results, comment out the previous
    ' For Each loops.
    For Each studentRecord In studentQuery4
        Console.WriteLine(studentRecord.Last & ", " & studentRecord.First &
                          ":  " & studentRecord.Rank)
    Next
    
  2. Générez et exécutez l’application en appuyant sur Ctrl + F5. Notez les résultats dans la fenêtre de console.

Autres exemples

Maintenant que vous comprenez les principes de base, voici une liste d’exemples supplémentaires qui illustrent la flexibilité et la puissance des requêtes LINQ. Chaque exemple est précédé d’une brève description de son action. Placez le pointeur de la souris sur la variable de résultat de la requête pour chaque requête afin de voir le type déduit. Utilisez une boucle For Each pour produire les résultats.

' Find all students who are seniors.
Dim q1 = From currentStudent In students
         Where currentStudent.Year = "Senior"
         Select currentStudent

' Write a For Each loop to execute the query.
For Each q In q1
    Console.WriteLine(q.First & " " & q.Last)
Next

' Find all students with a first name beginning with "C".
Dim q2 = From currentStudent In students
         Where currentStudent.First.StartsWith("C")
         Select currentStudent

' Find all top ranked seniors (rank < 40).
Dim q3 = From currentStudent In students
         Where currentStudent.Rank < 40 And currentStudent.Year = "Senior"
         Select currentStudent

' Find all seniors with a lower rank than a student who 
' is not a senior.
Dim q4 = From student1 In students, student2 In students
         Where student1.Year = "Senior" And student2.Year <> "Senior" And
               student1.Rank > student2.Rank
         Select student1
         Distinct

' Retrieve the full names of all students, sorted by last name.
Dim q5 = From currentStudent In students
         Order By currentStudent.Last
         Select Name = currentStudent.First & " " & currentStudent.Last

' Determine how many students are ranked in the top 20.
Dim q6 = Aggregate currentStudent In students
         Where currentStudent.Rank <= 20
         Into Count()

' Count the number of different last names in the group of students.
Dim q7 = Aggregate currentStudent In students
         Select currentStudent.Last
         Distinct
         Into Count()

' Create a list box to show the last names of students.
Dim lb As New System.Windows.Forms.ListBox
Dim q8 = From currentStudent In students
         Order By currentStudent.Last
         Select currentStudent.Last Distinct

For Each nextName As String In q8
    lb.Items.Add(nextName)
Next

' Find every process that has a lowercase "h", "l", or "d" in its name.
Dim letters() As String = {"h", "l", "d"}
Dim q9 = From proc In System.Diagnostics.Process.GetProcesses,
         letter In letters
         Where proc.ProcessName.Contains(letter)
         Select proc

For Each proc In q9
    Console.WriteLine(proc.ProcessName & ", " & proc.WorkingSet64)
Next

Informations supplémentaires

Une fois que vous êtes familiarisé avec les concepts de base de l’utilisation de requêtes, vous êtes prêt à lire la documentation et les exemples pour le type spécifique de fournisseur LINQ qui vous intéresse :

Voir aussi