Notes
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Une requête est une expression qui récupère les 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 différents types de sources de données, par exemple SQL pour les bases de données relationnelles et XQuery pour XML. Cela permet au développeur d’applications d’apprendre un nouveau langage de requête pour chaque type de source de données ou format de données pris en charge.
Language-Integrated Query (LINQ) simplifie la situation en offrant un modèle cohérent pour l’utilisation des données dans différents types de sources de données et de formats. Dans une requête LINQ, vous utilisez toujours 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 jeux de données et des entités ADO.NET, des collections .NET Framework et tout autre format source ou format pour lequel un fournisseur LINQ est disponible. Ce document décrit les trois phases de la création et de l’utilisation de requêtes LINQ de base.
Trois étapes d’une opération de requête
Les opérations de requête LINQ se composent de trois actions :
Obtenez la source de données ou les sources.
Créez la requête.
exécutez 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 pas de données uniquement en créant une requête. Ce point est abordé plus en détail plus loin dans cette rubrique.
L’exemple suivant illustre les trois parties d’une opération de requête. L’exemple utilise un tableau d’entiers comme source de données pratique à des fins de démonstration. Toutefois, les mêmes concepts s’appliquent également à d’autres sources de données.
Remarque
Dans la page Compiler, le Concepteur de projets (Visual Basic), vérifiez que l’option déduite est activée.
' 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
Étant donné que la source de données de l’exemple précédent est un tableau, elle prend implicitement en charge l’interface générique IEnumerable<T> . Il s’agit de ce fait qui vous permet d’utiliser un tableau comme source de données pour une requête LINQ. Les types qui prennent en charge IEnumerable<T> ou une interface dérivée, comme le générique IQueryable<T> , sont appelés types interrogeables.
En tant que type implicitement interrogeable, le tableau ne nécessite aucune modification ni traitement spécial pour servir de source de données LINQ. Il en va de même pour tout type de collection qui prend en charge IEnumerable<T>, y compris le générique List<T>, Dictionary<TKey,TValue>et d’autres classes dans la bibliothèque de classes .NET Framework.
Si les données sources n’implémentent IEnumerable<T>pas déjà, 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 travail de chargement d’un document XML dans un type interrogeable XElement , comme illustré 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 (Visual Basic).
' Create a data source from an XML document.
Dim contacts = XElement.Load("c:\myContactList.xml")
Avec LINQ to SQL, vous créez d’abord un mappage relationnel objet au moment du design, manuellement ou à l’aide des outils LINQ to SQL dans Visual Studio dans Visual Studio . Vous écrivez vos requêtes sur les objets et, au moment de l’exécution, LINQ to SQL gère la communication avec la base de données. Dans l’exemple suivant, customers
représente une table spécifique dans la base de données et Table<TEntity> prend en charge les génériques IQueryable<T>.
' 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 spécifiques de sources de données, consultez la documentation des différents fournisseurs LINQ. (Pour obtenir la liste de ces fournisseurs, consultez LINQ (requêteLanguage-Integrated).) La règle de base est simple : une source de données LINQ est n’importe quel objet qui prend en charge l’interface générique IEnumerable<T> ou une interface qui hérite de celle-ci.
Remarque
Les types tels que ArrayList ceux qui prennent en charge l’interface non générique IEnumerable peuvent également être utilisés comme sources de données LINQ. Pour obtenir un exemple qui utilise un ArrayList, consultez Comment : interroger une arrayList avec LINQ (Visual Basic).
Requête
Dans la requête, vous spécifiez les informations que vous souhaitez récupérer à partir de la source de données ou des sources. Vous avez également la possibilité de spécifier la façon dont ces informations doivent être triées, regroupées ou structurées avant leur retour. Pour activer 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 dans l’exemple suivant retourne tous les nombres pairs d’un tableau entier. 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 l’objectif spécifiques de chaque clause d’expression de requête sont abordés dans Basic Query Operations (Visual Basic). Pour plus d’informations, consultez Requêtes. 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 interrogeable. Le type de ce dernier est IEnumerable(Of Integer)
affecté par le compilateur à l’aide de evensQuery
l’inférence de type local.
Il est important de se rappeler que la variable de requête elle-même n’effectue aucune action et ne retourne aucune donnée. Elle stocke uniquement la définition de requête. Dans l’exemple précédent, il s’agit de la For Each
boucle qui exécute la requête.
Exécution des requêtes
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 autre mécanisme. Une requête peut être exécutée dès qu’elle est définie (exécution immédiate), ou la définition peut être stockée et la requête peut être exécutée ultérieurement (exécution différée).
Exécution différée
Une requête LINQ classique ressemble à celle de l’exemple précédent, dans laquelle evensQuery
elle est définie. Il crée la requête, mais ne l’exécute pas immédiatement. Au lieu de cela, la définition de requête est stockée dans la variable evensQuery
de requête. Vous exécutez la requête ultérieurement, généralement à l’aide d’une For Each
boucle, 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 appelé 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 For Each
boucle (number
dans l’exemple précédent). Étant donné que la variable de requête, evensQuery
contient la définition de requête plutôt que les résultats de la requête, vous pouvez exécuter une requête aussi souvent que vous le souhaitez à l’aide de la variable de requête plusieurs fois. Par exemple, vous pouvez avoir une base de données dans votre application en cours de mise à jour en permanence par une application distincte. Une fois que vous avez créé une requête qui récupère des données de cette base de données, vous pouvez utiliser une For Each
boucle pour exécuter la requête à plusieurs reprises, en récupérant les données les plus récentes à chaque fois.
L’exemple suivant montre comment fonctionne l’exécution différée. Une fois evensQuery2
défini et exécuté avec une For Each
boucle, comme dans les exemples précédents, certains éléments de la source numbers
de données sont modifiés. Ensuite, une deuxième For Each
boucle s’exécute evensQuery2
à nouveau. Les résultats sont différents la deuxième fois, car la For Each
boucle exécute à nouveau la requête, en utilisant les nouvelles valeurs dans numbers
.
Dim numberArray() = {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 des requêtes, la définition de requête est stockée dans une variable de requête pour 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 nécessite l’accès à des é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. Exemples : Count
, Max
, Average
et First
. Ces opérateurs de requête standard exécutent la requête dès qu’elles sont appliquées 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érationsd’élément et Opérations quantificateur.
La requête suivante retourne un nombre de nombres pairs dans un tableau d’entiers. La définition de requête n’est pas enregistrée et numEvens
est simple Integer
.
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 Aggregate
méthode.
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 ou ToArray
la ToList
méthode sur une requête (immédiate) ou une variable de requête (différée), comme indiqué 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 = evensQuery3.ToArray()
Dans les exemples précédents, evensQuery3
il s’agit d’une variable de requête, mais evensList
il s’agit d’une liste et evensArray
d’un tableau.
L’utilisation ToList
ou ToArray
la force de l’exécution immédiate est particulièrement utile dans les scénarios dans lesquels vous souhaitez exécuter la requête immédiatement et mettre en cache les résultats dans un objet de collection unique. Pour plus d’informations sur ces méthodes, consultez Conversion de types de données.
Vous pouvez également exécuter une requête à l’aide d’une IEnumerable
méthode telle que la IEnumerable.GetEnumerator méthode.