En tant que développeurs de logiciels, nous passons beaucoup de temps à extraire et à afficher des données provenant de nombreuses sources de données différentes. Qu'il s'agisse d'un service Web XML ou d'une base de données relationnelle complète, nous avons été contraints d'apprendre différentes méthodes d'accès aux données. Ne serait-il pas formidable que la méthode d'accès soit la même pour toutes les sources de données? Eh bien, nous avons de la chance parce que, depuis la publication de C # 3.0 et du .NET 3.5 Framework, LINQ est venu pour changer le jeu pour toujours.
Sur la plate-forme .NET, nous utilisons et utilisons encore ADO.NET
pour accéder à différentes sources de données. La communauté open source a également fourni
les développeurs avec un certain nombre d'alternatives.
Language Integrated Query est le nouvel ajout au .NET
famille et comme son nom l'indique, c'est le genre d'accès aux données de style de requête qui
est entièrement pris en charge par la langue pour unifier efficacement la façon dont nous accédons aux données
et pour rendre nos vies plus faciles. LINQ est capable de cibler un certain nombre de sources différentes, à savoir Oracle,
MSSQL, XML et quelques autres, mais pour le moment nous allons nous concentrer sur le plus fondamental
tous, LINQ to Objects.
Normalement, traiter et raffiner les données de nos listes
et diverses autres structures de données, nous avons utilisé la boucle 'foreach' ou une autre
type de méthode de boucle pour parcourir les objets et les traiter un par
une selon certaines conditions. C’est bien, mais franchement, cela demande beaucoup de
codage de base que nous souhaitons tous ne pas avoir à écrire. Essentiellement, nous avons dû dire au
compilateur chaque détail du processus afin de manipuler les données.
C’est précisément là que LINQ brille le mieux. Ce que LINQ nous permet
à faire est de simplement dire au compilateur ce que nous aimerions effectuer et laisser le compilateur travailler
le meilleur moyen d'y parvenir. Si vous avez déjà utilisé la syntaxe SQL, les ressemblances énormes
entre LINQ et tous les dialectes de SQL sera la première chose que vous remarquerez.
Comme SQL, LINQ prend également en charge les options "select", "from", "where", "join", "group by"
et "commander par" mots-clés. Voici un exemple simple d'interrogation d'une liste d'objets:
Initialisation de la liste:
listeListOfCars = nouvelle liste () voiture neuve name = "Toyota", propriétaire = "Alex", modèle = 1992, voiture neuve name = "Mitsubishi", propriétaire = "Jeff", modèle = 2005, voiture neuve name = "Land Rover ", propriétaire =" Danny ", modèle = 2001, voiture neuve name =" BMW ", propriétaire =" Danny ", modèle = 2006, voiture neuve name =" Subaru ", propriétaire =" Smith ", modèle = 2003;
La requête:
IEnumerableQueryResult = from car dans ListOfCars, sélectionnez car;
La première partie du code précédent remplit simplement une liste
avec quatre instances de la classe 'Car'. La partie suivante du code, cependant, utilise le
Mots-clés "from" et "select" pour sélectionner un groupe d'objets. La principale différence
entre SQL et LINQ est que le mot clé "from" vient avant le "select"
mot-clé car nous devons d’abord définir l’objet sur lequel nous souhaitons opérer. finalement
la clause "select" indique au compilateur ce que nous souhaitons extraire dans cette requête. Ce qui précède
le code extrait simplement tout ce qui est dans la liste et l'assigne au "QueryResult"
variable.
Lorsque nous interrogeons des objets à partir d’objets (LINQ to Objects), notre
les requêtes renvoient toujours un "IEnumrable
Le type "IEnumerable" est le genre de liste qui expose l'énumérateur, qui
prend en charge une simple itération sur une collection non générique, et
est le type de chaque entrée dans la liste.
Ne vous inquiétez pas si vous n'êtes pas familier avec les "énumérateurs" et les "génériques". Juste
rappelez-vous que le résultat des requêtes LINQ est toujours une collection comme des données
structure qui permet de parcourir à travers elle en utilisant une boucle comme indiqué
mugissement:
foreach (voiture dans QueryResult) Console.WriteLine (car.name);
Nous avons appris que LINQ renvoie toujours une structure de collection similaire.
à d'autres listes. Cependant, la requête LINQ n’est exécutée que lorsque son résultat est
accessible par un autre morceau de code, comme la boucle "foreach" ci-dessus. C'est pour
nous permettent de définir en continu la requête sans le surcoût en réévaluant
chaque nouvelle étape de la requête.
Jusqu'ici tout va bien; mais la plupart du temps, nos requêtes auront besoin
être plus complexe; alors essayons de projeter des données. En SQL, Projection signifie sélectionner
le nom de la (des) colonne (s) de la (des) table (s) que l'on souhaite voir apparaître dans le résultat
de la requête. Dans le cas de LINQ to Objects, l'exécution de la projection entraînera
dans un type de résultat de requête différent du type d'objet que nous effectuons
requête sur.
Nous pouvons faire deux types de projections. nous pouvons
soit effectuer une projection basée sur un type d'objet existant, soit aller complètement
dans l'autre sens en utilisant des types anonymes. L’exemple suivant est du premier
gentil:
IEnumerableQueryResult = from car dans ListOfCars, sélectionnez new CarOwner owner_name = car.owner;
Dans le code précédent, le type du résultat de la requête est déclaré comme
également utilisé le "nouveau" mot-clé et ont fait quelques tâches à l'intérieur du bouclé
supports. Dans le code ci-dessus, utiliser "select" avec le mot-clé "new" indique au
compilateur pour instancier un nouvel objet 'CarOwner' pour chaque entrée du résultat de la requête.
De plus, en affectant des valeurs au nouveau type, nous avons initialisé chaque instance.
de la classe 'CarOwner'.
Néanmoins, si vous n'avez pas déjà défini un type pour
utiliser, vous pouvez toujours effectuer des projections en utilisant des types anonymes.
Ce serait un gros problème si, pour chaque projection, vous étiez
forcé de créer un nouveau type. C’est pourquoi, à partir de C # 3.0, la prise en charge de Anonymous
types a été ajouté à la langue. Un type anonyme est déclaré en utilisant le "var"
mot-clé. Il indique au compilateur que le type de la variable est inconnu jusqu'à ce que
il est assigné pour la première fois.
var QueryResult = from car dans ListOfCars, sélectionnez new car_name = car.name, owner_name = car.owner; foreach (entrée var dans QueryResult) Console.WriteLine (entry.car_name);
Ce qui précède est un exemple d’exécution d’une requête avec Anonymous.
les types. Le seul problème à prendre en compte est que le compilateur ne
autoriser le retour de types anonymes à partir de méthodes.
Accéder aux propriétés d'un type anonyme est facile. Dans Visual Studio 2008, le code
Completion / Intellisense répertorie également les propriétés exposées par le type anonyme.
Habituellement, dans le cadre de la requête LINQ, nous devons également affiner la
résultat de la requête en spécifiant une condition. Comme SQL, LINQ utilise aussi le "où"
clause indiquant au compilateur quelles conditions sont acceptables.
IEnumerableQueryResult = de voiture dans ListOfCars où car.name == "Subaru" sélectionne voiture;
Le code précédent illustre l'utilisation de la clause "where" et
la condition à suivre. Pour mieux définir plusieurs conditions, LINQ prend en charge
les constructions 'et' (&& amp) et 'ou' (||). La partie "où" de la requête doit toujours être un
Expression booléenne, sinon le compilateur se plaindra.
Lors de la recherche d'objets, il est possible de s'appuyer sur la requête
la cible est déjà triée. Si ce n'est pas le cas, LINQ peut s'en occuper
en utilisant la clause "order by" qui assurera le résultat de votre requête
correctement trié.
IEnumerableQueryResult = from car dans ListOfCars orderby car.model, sélectionnez voiture;
Si vous exécutez le code ci-dessus, vous verrez que le résultat de la
la requête est triée par ordre croissant. Vous pouvez modifier l'ordre en utilisant les options "croissant" et "décroissant"
mots-clés, puis modifiez l'ordre en spécifiant plus d'un champ à trier
par. Le code suivant montre comment:
IEnumerableQueryResult = de voiture dans ListOfCars orderby car.model décroissant, sélectionnez voiture;
LINQ permet également de grouper le résultat de la requête par la valeur d’un
propriété spécifique comme indiqué dans cet exemple:
var QueryResult = d'une voiture du groupe ListOfCars, voiture par propriétaire. propriétaire dans wawnersGroup select carOwnersGroup.Key;
Comme vous pouvez le constater, LINQ supporte la clause "group by" pour
spécifier quel objet et par quelle propriété grouper. Le mot clé "en" sera
puis nous permettre de projeter sur un résultat de regroupement auquel on peut accéder par la "touche"
propriété.
LINQ prend en charge la jonction de données de différentes collections en une seule.
résultat de la requête. Vous pouvez le faire en utilisant le mot-clé "join" pour spécifier quels objets
pour rejoindre et utiliser le mot clé "on" pour spécifier la relation de correspondance entre
les deux objets.
Initialisation de la liste associée:
listeListOfCars = nouvelle liste () voiture neuve name = "Mitsubishi", propriétaire = "Jeff", modèle = 2005, voiture neuve name = "Land Rover", propriétaire = "Danny", modèle = 2001, voiture neuve name = " Subaru ", propriétaire =" Smith ", modèle = 2003, voiture neuve name =" Toyota ", propriétaire =" Alex ", modèle = 1992, voiture neuve name =" BMW ", propriétaire =" Danny ", modèle = 2006,; liste ListOfCarOwners = nouvelle liste () new CarOwner owner_name = "Danny", age = 22, nouveau CarOwner owner_name = "Jeff", age = 35, new CarOwner owner_name = "Smith", age = 19, nouveau CarOwner owner_name = "Alex", age = 40;
Question:
var QueryResult = from car in ListOfCars rejoindre le propriétaire dans ListOfCarOwners on car.owner est égal à carowner.owner_name, sélectionnez new name = car.name, owner = car.owner, owner_age = carowner.age;
Dans le code ci-dessus, en utilisant un type anonyme, nous avons rejoint
les deux objets dans un seul résultat de requête.
Jusqu'à présent, nous avons appris à utiliser LINQ pour construire un appartement
liste résultat de la requête. Avec LINQ, il est également possible de réaliser une requête hiérarchique
résultat en utilisant "GroupJoin". En termes simples, nous pourrions assigner des objets à
propriétés de chaque entrée avec une requête LINQ.
listeListOfCars = nouvelle liste () voiture neuve name = "Mitsubishi", propriétaire = "Jeff", modèle = 2005, voiture neuve name = "Land Rover", propriétaire = "Danny", modèle = 2001, voiture neuve name = " Subaru ", propriétaire =" Smith ", modèle = 2003, voiture neuve name =" Toyota ", propriétaire =" Alex ", modèle = 1992, voiture neuve name =" BMW ", propriétaire =" Danny ", modèle = 2006,; liste ListOfCarOwners = nouvelle liste () new CarOwner owner_name = "Danny", age = 22, nouveau CarOwner owner_name = "Jeff", age = 35, new CarOwner owner_name = "Smith", age = 19, nouveau CarOwner owner_name = "Alex", age = 40; var QueryResult = du propriétaire de ListOfCarOwners rejoint la voiture de ListOfCars sur carowner.owner_name est égal à car.owner dans carsGroup select new new name = carowner.owner_name, cars = carsGroup; foreach (var carOwner dans QueryResult) foreach (var voiture dans carOwner.cars) Console.WriteLine ("Nom du propriétaire: 0, nom de la voiture: 1, modèle de voiture: 2", carOwner.name, car.name , modèle de voiture);
Dans l'exemple ci-dessus, la clause "Join" est suivie d'un "into"
partie. Cela diffère de l'opération de jointure précédente que nous avons examinée. Ici, le "en"
Cette clause permet de regrouper les voitures par le propriétaire (dans carsGroup) et d’affecter le groupe à la
"voitures" propriété de type anonyme.
Jusqu'ici, tout ce que nous avons vu a été pris en charge par le C # 3.0
syntaxe. Cependant, il y a toujours un grand nombre d'opérations que C # 3.0 ne fait pas
soutien. Les opérateurs de requête standard fournissent des fonctionnalités de requête, notamment:
filtrage, projection, agrégation, tri et plus. Ces opérations sont donc supportées
comme méthodes de la bibliothèque LINQ et peuvent être exécutés sur le résultat d’une requête comme indiqué dans le
capture d'écran suivante:
Ces opérateurs sont énumérés ci-dessous pour votre référence.
LINQ s’est avéré très utile pour interroger des objets, et la syntaxe semblable à celle de SQL facilite la
apprendre et utiliser. En outre, le grand nombre d’opérateurs standard permet d’enchaîner plusieurs opérateurs
effectuer des requêtes complexes. Dans la suite de ce didacticiel, nous verrons comment LINQ peut être utilisé pour
interroger des bases de données et du contenu XML…