IEnumerable<T> vs IQueryable<T> : que choisir en C# ? Analyse complète

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

IEnumerable<T> vs IQueryable<T> : un duel qui décidera du sort de votre application

\n\n

Avez-vous déjà réfléchi à pourquoi votre requête de base de données ralentit, alors qu'il y a très peu de données ? Ou pourquoi, après avoir ajouté une seule ligne de code, votre application se transforme en tortue ? Vous avez probablement rencontré le dilemme classique : IEnumerable<T> ou IQueryable<T> ? Ce ne sont pas simplement deux interfaces du monde C# et LINQ. Ce sont deux mondes différents, deux approches du travail avec les données. L'une est destinée aux collections locales, l'autre aux sources distantes, comme les bases de données. Dans cet article, nous ne nous contenterons pas d'énumérer les différences, mais nous les analyserons avec des exemples concrets, afin que vous ne tombiez plus jamais dans le piège des performances.

\n\n

Qui est qui : concepts de base

\n\n

Commençons par les bases. IEnumerable<T> est une interface qui représente une séquence d'éléments en mémoire. Elle est idéale pour travailler avec des collections telles que List<T>, Array ou Dictionary. Lorsque vous utilisez IEnumerable, toutes les opérations (filtrage, tri) sont exécutées côté client, c'est-à-dire dans votre application.

\n\n

IQueryable<T> est une interface plus avancée, conçue pour travailler avec des sources de données externes (bases de données, services web). Elle ne stocke pas les données, mais construit un arbre d'expressions (Expression Tree). Cela permet au fournisseur LINQ (par exemple, Entity Framework) de transformer votre code C# en une requête SQL efficace et de l'exécuter côté serveur.

\n\n

La phrase clé à retenir : IEnumerable fonctionne en mémoire, IQueryable fonctionne côté source de données.

\n\n

La différence principale : où et quand la logique est exécutée

\n\n

Imaginez que vous devez filtrer une liste de 10 000 produits coûtant plus de 1000 roubles, et les trier par prix.

\n\n

Exemple 1 : IEnumerable (filtrage en mémoire)

\n
// Supposons que products soit un List<Product> (IEnumerable)\nvar expensiveProducts = products\n    .Where(p => p.Price > 1000)\n    .OrderBy(p => p.Price)\n    .ToList();\n
\n

Que se passe-t-il ici ? D'abord, la totalité des 10 000 produits est chargée en mémoire. Ensuite, C# applique le filtre Where et le tri OrderBy dans votre application. Si vous avez 10 000 enregistrements, ce n'est pas critique. Mais s'il y en a 10 millions, l'application plantera ou se bloquera.

\n\n

Exemple 2 : IQueryable (filtrage sur le serveur de base de données)

\n
// Supposons que dbContext.Products soit un DbSet<Product> (IQueryable)\nvar expensiveProducts = dbContext.Products\n    .Where(p => p.Price > 1000)\n    .OrderBy(p => p.Price)\n    .ToList();\n
\n

Ici, la magie opère : IQueryable ne charge pas les données immédiatement. Au lieu de cela, il construit une requête SQL : SELECT * FROM Products WHERE Price > 1000 ORDER BY Price. Cette requête est envoyée à la base de données, qui ne retourne que les données filtrées et triées. En mémoire, vous ne recevez que ce dont vous avez besoin. L'économie de ressources est colossale.

\n\n

Exemple pratique : le piège de ToList()

\n\n

L'une des erreurs les plus fréquentes chez les développeurs débutants est l'appel prématuré à ToList() ou ToArray(). Cela transforme IQueryable en IEnumerable.

\n\n

Mauvais code (tue les performances) :

\n
var allProducts = dbContext.Products.ToList(); // On charge TOUTES les données en mémoire !\nvar filteredProducts = allProducts.Where(p => p.Price > 1000).ToList();\n
\n

Dans cet exemple, nous chargeons d'abord toute la table Products en mémoire, puis nous la filtrons. C'est l'équivalent de décharger tout l'entrepôt sur le parking, puis de chercher la bonne boîte dans le tas.

\n\n

Bon code (optimal) :

Blogs

Book Recommendations