web-dev-qa-db-fra.com

Différence entre IQueryable, ICollection, IList & IDictionary interface

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.

48
Praneeth

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 #).

  • ICollection est la plus basique des interfaces que vous avez répertoriées. C'est une interface énumérable qui prend en charge un compte et c'est à peu près tout.
  • IList est tout ce que ICollection est, mais il prend également en charge l'ajout et la suppression d'éléments, la récupération d'éléments par index, etc. C'est l'interface la plus couramment utilisée pour les "listes d'objets", ce qui est vague je sais.
  • IQueryable est une interface énumérable qui prend en charge LINQ. Vous pouvez toujours créer un IQueryable à partir d'une IList et utiliser LINQ to Objects, mais vous trouvez également IQueryable utilisé pour l'exécution différée des instructions SQL dans LINQ to SQL et LINQ to Entities.
  • IDictionary est un animal différent dans le sens où il s'agit d'une cartographie de clés uniques aux valeurs. Il est également énumérable dans la mesure où vous pouvez énumérer les paires clé/valeur, mais sinon, il sert un objectif différent de celui que vous avez répertorié.

La documentation MSDN pour chacun d'eux est décente, donc je commencerais par là pour compléter votre compréhension.

104
John Bledsoe

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:

  1. Nombre total de requêtes lancées: 1
  2. Texte de requête: 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:

  1. Nombre total de requêtes lancées: 1
  2. Texte de requête capturé dans le profileur SQL: 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.

3
RBT

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

  1. Si vous écrivez la requête sur les données de la base de données, utilisez IQueryable.
  2. Si vous interrogez les données en cours, utilisez IEnumerable. IEnumerable a une méthode GetEnumerator (), Current () et MoveNext ().
3
gunny 229