J'essaie de comprendre la différence entre l'interface IQueryable, ICollection, IList et IDictionary qui est plus rapide pour les opérations de base comme l'itération, l'indexation, la requête et plus encore.
quelle classe comme Collection, List, Dictionary, etc. serait utile pour lancer avec ces interfaces et quand devrions-nous utiliser ces classes. Avantages de base de l'utilisation de ces classes par rapport aux autres.
J'ai essayé de lire d'autres articles avec des questions similaires, mais rien n'a répondu à mes questions complètes. Merci pour l'aide.
Toutes ces interfaces héritent de IEnumerable, que vous devez vous assurer de bien comprendre. Cette interface vous permet essentiellement d'utiliser la classe dans une instruction foreach
(en C #).
La documentation MSDN pour chacun d'eux est décente, donc je commencerais par là pour compléter votre compréhension.
J'ai remarqué plusieurs problèmes dans la réponse de @ gunny229 ci-dessus, c'est pourquoi j'écris ce message. J'ai également mentionné ces problèmes dans la zone de commentaires de son article. Pour corriger ce message, j'aurais dû réécrire presque tout le message, alors j'ai pensé à créer le mien. Je n'ai pas l'intention de répondre à la question de OP dans son intégralité, mais je tiens à souligner la différence entre IQueryable et IEnumerable lors de l'utilisation de LINQ to SQL.
J'ai créé la structure suivante dans DB (script DDL):
CREATE TABLE [dbo].[Employee]([PersonId] [int] NOT NULL PRIMARY KEY,[Salary] [int] NOT NULL)
Voici le script d'insertion d'enregistrement (script DML):
INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(1, 20)
INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(2, 30)
INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(3, 40)
INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(4, 50)
INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(5, 60)
GO
Maintenant, mon objectif était simplement d'obtenir les 2 meilleurs enregistrements de la table Employee
dans la base de données. J'ai donc ajouté un élément ADO.NET Entity Data Model dans mon application console pointant vers la table Employee
dans ma base de données et j'ai commencé à écrire des requêtes LINQ.
Code pour la route IQueryable:
using (var efContext = new EfTestEntities())
{
IQueryable<int> employees = from e in efContext.Employees select e.Salary;
employees = employees.Take(2);
foreach (var item in employees)
{
Console.WriteLine(item);
}
}
Lorsque j'ai commencé à exécuter ce programme, j'avais également démarré une session de SQL Query profiler sur mon instance SQL Server et voici le résumé de l'exécution:
SELECT TOP (2) [c].[Salary] AS [Salary] FROM [dbo].[Employee] AS [c]
C'est juste que IQueryable
est assez intelligent pour appliquer la clause Top (2)
du côté du serveur de base de données lui-même, de sorte qu'il n'apporte que 2 enregistrements sur 5 sur le fil. Aucun autre filtrage en mémoire n'est nécessaire du tout côté ordinateur client.
Code pour la route IEnumerable:
using (var efContext = new EfTestEntities())
{
IEnumerable<int> employees = from e in efContext.Employees select e.Salary;
employees = employees.Take(2);
foreach (var item in employees)
{
Console.WriteLine(item);
}
}
Résumé de l'exécution dans ce cas:
SELECT [Extent1].[Salary] AS [Salary] FROM [dbo].[Employee] AS [Extent1]
Maintenant, la chose est IEnumerable
a apporté tous les 5 enregistrements présents dans la table Salary
puis a effectué un filtrage en mémoire sur l'ordinateur client pour obtenir les 2 premiers enregistrements. Donc, plus de données (3 enregistrements supplémentaires dans ce cas) ont été transférées inutilement sur le fil.
IQueryable, IList, IDictionary, ICollection hérite de l'interface IEnumerable. Toutes les interfaces de la collection de types hériteront de l'interface IEnumerable.
Différences entre IEnumerable et IQueryable IEnumerable: - lorsque vous exécutez une requête qui retourne de type IEnumerable. IEnumerable exécute d'abord la première requête, puis exécute les sous-requêtes écrites pour cette requête.
Exemple: - Si vous voulez obtenir les 10 premiers enregistrements de population d'un pays particulier, la requête que nous utiliserons dans LinQ est
IEnumerable _Population = de s en Inde sélectionnez s.population; // First Query _Population = _Population.take (10); // Second Query
Maintenant, si nous exécutons cette requête, la première requête sera exécutée en premier, l'IEnumerable obtiendra les enregistrements de toute la population du serveur SQL, puis il stockera les données dans la mémoire en cours, puis il exécutera les 10 premières populations de la prochaine requête. (L'exécution a lieu deux fois sur le serveur SQL).
si nous exécutons la même requête en utilisant IQueryable.
IQueryable _Population = de s en Inde sélectionnez s.population; // First Query _Population = _Population.take (10); // Second Query
dans cet IQueryable, il exécutera les deux requêtes en même temps dans le sens où il obtiendra la population qui se trouve dans le top 10 dans une seule requête au lieu d'obtenir les données et de filtrer à nouveau les 10 premières (exécution unique sur le serveur SQL). .
Conclusion pour IQueryable et IEnumerable