Partager via


Écriture de votre première requête LINQ (Visual Basic)

Mise à jour : novembre 2007

Une requête est une expression qui récupère des données d'une source de données. Les requêtes sont exprimées dans un langage de requête dédié. Au fil du temps, différents langages ont été développés pour les différents types de sources de données, par exemple, SQL pour les bases de données relationnelles et XQuery pour le XML. Les développeurs d'applications doivent donc apprendre un nouveau langage de requête pour chaque type de source de données ou de format de données pris en charge.

LINQ (Language Integrated Query) simplifie les choses en proposant un modèle cohérent qui permet d'utiliser des données de types de sources et de formats divers. Dans une requête LINQ, vous travaillez toujours avec des objets. Vous utilisez les mêmes modèles de codage de base pour interroger et transformer des données dans des documents XML, des bases de données SQL, des groupes de données et des entités ADO.NET, des collections .NET Framework et les autres sources ou formats pour lesquels un fournisseur LINQ est disponible. Ce document décrit les trois phases de création et d'utilisation de requêtes LINQ de base.

Trois étapes d'une opération de requête

Les opérations de requête LINQ incluent trois opérations :

  1. Obtenir la source ou les sources de données.

  2. Créer la requête.

  3. Exécuter la requête.

Dans LINQ, l'exécution d'une requête est distincte de la création de la requête. Vous ne récupérez aucune donnée en créant uniquement une requête. Ce point est abordé plus en détail ultérieurement dans cette rubrique.

L'exemple suivant présente les trois parties d'une opération de requête. Un tableau d'entiers est utilisé comme source de données, à des fins de démonstration. Toutefois, ces concepts s'appliquent également à d'autres sources de données.

' Data source.
Dim numbers() As Integer = {0, 1, 2, 3, 4, 5, 6}

' Query creation.
Dim evensQuery = From num In numbers _
                 Where num Mod 2 = 0 _
                 Select num

' Query execution.
For Each number In evensQuery
    Console.Write(number & " ")
Next

Sortie :

0 2 4 6

Source de données

La source de données de l'exemple précédent étant un tableau, elle prend en charge implicitement l'interface IEnumerable<T> générique. Cela vous permet d'utiliser un tableau comme source de données pour une requête LINQ. Les types qui prennent en charge IEnumerable (Of T) ou une interface dérivée, telle que le IQueryable<T> générique, sont des types requêtables.

En tant que type implicitement requêtable, le tableau ne nécessite aucune modification ni traitement spécial pour servir de source de données LINQ. Cela s'applique également pour tout type de collection prenant en charge IEnumerable (Of T), y compris le List<T> générique, Dictionary<TKey, TValue> et d'autres classes dans la bibliothèque de classes .NET Framework.

Si les données sources n'implémentent pas déjà IEnumerable (Of T), un fournisseur LINQ est nécessaire pour implémenter les fonctionnalités des opérateurs de requête standard pour cette source de données. Par exemple, LINQ to XML gère le chargement d'un document XML dans un type XElement requêtable, comme présenté dans l'exemple suivant. Pour plus d'informations sur les opérateurs de requête standard, consultez Vue d'ensemble des opérateurs de requête standard.

' Create a data source from an XML document.
Dim contacts As XElement = XElement.Load("c:\myContactList.xml")

Avec LINQ to SQL, vous créez tout d'abord un mappage objet/relationnel au moment du design, soit manuellement, soit à l'aide du Concepteur Objet/Relationnel (Concepteur O/R). Vous écrivez vos requêtes sur les objets et LINQ to SQL gère la communication avec la base de données au moment de l'exécution. Dans l'exemple suivant, customers représente une table spécifique dans la base de données et Table<TEntity> prend en charge le IQueryable<T> générique.

' Create a data source from a SQL table.
Dim db As New DataContext("C:\Northwind\Northwnd.mdf")
Dim customers As Table(Of Customer) = db.GetTable(Of Customer)

Pour plus d'informations sur la création de types de sources de données spécifiques, consultez la documentation des différents fournisseurs LINQ. Pour obtenir la liste de ces fournisseurs, consultez LINQ (Language-Integrated Query). La règle de base est simple : une source de données LINQ correspond à tout type d'objet qui prend en charge l'interface IEnumerable<T> générique ou une interface qui hérite de celle-ci.

Remarque :

Les types tels que ArrayList qui prennent en charge l'interface IEnumerable non générique peuvent également être utilisés comme sources de données LINQ. Pour obtenir un exemple qui utilise un ArrayList, consultez Comment : interroger un ArrayList avec LINQ.

Requête

Dans la requête, vous spécifiez les informations à récupérer de la source ou des sources de données. Vous pouvez également spécifier comment ces informations doivent être triées, regroupées ou structurées avant d'être retournées. Pour permettre la création de requêtes, Visual Basic a incorporé une nouvelle syntaxe de requête dans le langage.

Lorsqu'elle est exécutée, la requête de l'exemple suivant retourne tous les nombres pairs d'un tableau d'entiers, numbers.

' Data source.
Dim numbers() As Integer = {0, 1, 2, 3, 4, 5, 6}

' Query creation.
Dim evensQuery = From num In numbers _
                 Where num Mod 2 = 0 _
                 Select num

' Query execution.
For Each number In evensQuery
    Console.Write(number & " ")
Next

L'expression de requête contient trois clauses : From, Where et Select. La fonction et le but spécifiques de chaque clause d'expression de requête sont expliqués dans Opérations de requête de base (Visual Basic). Pour plus d'informations, consultez Requêtes (Visual Basic). Notez que dans LINQ, une définition de requête est souvent stockée dans une variable et exécutée ultérieurement. La variable de requête, telle que evensQuery dans l'exemple précédent, doit être un type requêtable. Le type d'evensQuery est IEnumerable(Of Integer) et est assigné par le compilateur à l'aide de l'inférence de type de variable locale.

Rappelez-vous que la variable de requête elle-même n'effectue aucune action et ne retourne pas de données. Elle stocke seulement la définition de la requête. Dans l'exemple précédent, c'est la boucle For Each qui exécute la requête.

Exécution de requête

L'exécution de requête est distincte de la création de requête. La création de requête définit la requête mais l'exécution est déclenchée par un mécanisme différent. Il est possible d'exécuter une requête dès qu'elle est définie (exécution immédiate) ou de stocker la définition et d'exécuter la requête ultérieurement (exécution différée).

Exécution différée

Une requête LINQ type est semblable à celle de l'exemple précédent, dans lequel evensQuery est défini. La requête est créée mais n'est pas exécutée immédiatement. À la place, la définition de la requête est stockée dans la requête de variable evensQuery. Vous exécutez la requête ultérieurement, en général à l'aide d'une boucle For Each qui retourne une séquence de valeurs ou en appliquant un opérateur de requête standard tel que Count ou Max. Ce processus est connu sous le nom d'exécution différée.

' Query execution that results in a sequence of values.
For Each number In evensQuery
    Console.Write(number & " ")
Next

' Query execution that results in a single value.
Dim evens = evensQuery.Count()

Pour une séquence de valeurs, vous accédez aux données récupérées à l'aide de la variable d'itération dans la boucle For Each (number dans l'exemple précédent). Comme la variable de requête, evensQuery, conserve la définition de la requête plutôt que les résultats, vous pouvez exécuter une requête aussi souvent que vous le souhaitez en utilisant la variable de requête plusieurs fois. Par exemple, vous pouvez avoir une base de données dans votre application mise à jour continuellement par une application séparée. Après avoir créé une requête qui récupère des données de cette base de données, vous pouvez utiliser une boucle For Each pour exécuter la requête à plusieurs reprises, en récupérant à chaque fois les données les plus récentes.

L'exemple suivant présente le fonctionnement de l'exécution différée. Une fois que vous avez défini et exécuté evensQuery2 avec une boucle For Each, comme dans les exemples précédents, certains éléments de la source de données numbers sont modifiés. Ensuite, une deuxième boucle For Each exécute encore evensQuery2. Les résultats sont différents la deuxième fois car la boucle For Each exécute encore la requête, à l'aide des nouvelles valeurs dans numbers.

Dim numberArray() As Integer = {0, 1, 2, 3, 4, 5, 6}

Dim evensQuery2 = From num In numberArray _
                  Where num Mod 2 = 0 _
                  Select num

Console.WriteLine("Evens in original array:")
For Each number In evensQuery2
    Console.Write("  " & number)
Next
Console.WriteLine()

' Change a few array elements.
numberArray(1) = 10
numberArray(4) = 22
numberArray(6) = 8

' Run the same query again.
Console.WriteLine(vbCrLf & "Evens in changed array:")
For Each number In evensQuery2
    Console.Write("  " & number)
Next
Console.WriteLine()

Sortie :

Evens in original array:

0 2 4 6

Evens in changed array:

0 10 2 22 8

Exécution immédiate

Dans l'exécution différée de requêtes, la définition de la requête est stockée dans une variable de requête en vue d'une exécution ultérieure. Dans l'exécution immédiate, la requête est exécutée au moment de sa définition. L'exécution est déclenchée lorsque vous appliquez une méthode qui requiert l'accès aux éléments individuels du résultat de la requête. L'exécution immédiate est souvent forcée à l'aide de l'un des opérateurs de requête standard qui retournent des valeurs uniques. Count, Max, Average et First en sont quelques exemples. Ces opérateurs de requête standard exécutent la requête dès leur application pour calculer et retourner un résultat singleton. Pour plus d'informations sur les opérateurs de requête standard qui retournent des valeurs uniques, consultez Opérations d'agrégation, Opérations d'élément et Opérations de quantificateur.

La requête suivante retourne un décompte des nombres pairs dans un tableau d'entiers. La définition de la requête n'est pas enregistrée et numEvens est un Integer simple.

Dim numEvens = (From num In numbers _
                Where num Mod 2 = 0 _
                Select num).Count()

Vous pouvez obtenir le même résultat à l'aide de la méthode Aggregate.

Dim numEvensAgg = Aggregate num In numbers _
                  Where num Mod 2 = 0 _
                  Select num _
                  Into Count()

Vous pouvez également forcer l'exécution d'une requête en appelant la méthode ToList ou ToArray sur une requête (exécution immédiate) ou sur une variable de requête (exécution différée), comme présenté dans le code suivant.

' Immediate execution.
Dim evensList = (From num In numbers _
                 Where num Mod 2 = 0 _
                 Select num).ToList()

' Deferred execution.
Dim evensQuery3 = From num In numbers _
                  Where num Mod 2 = 0 _
                  Select num
' . . .
Dim evensArray = evensQuery.ToArray()

Dans les exemples précédents, evensQuery3 est une variable de requête, mais evensList est une liste et evensArray un tableau.

L'utilisation de ToList ou de ToArray pour forcer l'exécution immédiate est particulièrement utile lorsque vous souhaitez exécuter immédiatement la requête et mettre en cache les résultats dans un objet de collection singleton. Pour plus d'informations sur ces méthodes, consultez Conversion de types de données.

Vous pouvez également exécuter une requête en utilisant une méthode IEnumerable telle que la GetEnumerator, méthode (objet Collection).

Voir aussi

Tâches

Exemples de requêtes (Visual Basic)

Concepts

Vue d'ensemble du Concepteur O/R

Inférence de type local

Vue d'ensemble des opérateurs de requête standard

Introduction à LINQ dans Visual Basic

Autres ressources

Mise en route de LINQ dans Visual Basic

Exemples LINQ

LINQ en Visual Basic

Requêtes (Visual Basic)