Retourner IEnumerable vs. IQueryable
Oui, les deux vous donneront une exécution différée.
La différence est que IQueryable<T> est l’interface qui permet à LINQ-to-SQL (LINQ-to-n’importe quoi en réalité) de fonctionner. Donc si vous affinez davantage votre requête sur un IQueryable<T>, cette requête sera exécutée dans la base de données, si possible.
Pour le cas IEnumerable<T>, ce sera du LINQ-to-object, ce qui signifie que tous les objets correspondant à la requête originale devront être chargés en mémoire depuis la base de données.
En code :
IQueryable<Customer> custs = ...;
// Later on...
var goldCustomers = custs.Where(c => c.IsGold);
Ce code exécutera du SQL pour sélectionner uniquement les clients gold. Le code suivant, en revanche, exécutera la requête originale dans la base de données, puis filtrera les clients non-gold en mémoire :
IEnumerable<Customer> custs = ...;
// Later on...
var goldCustomers = custs.Where(c => c.IsGold);
C’est une différence assez importante, et travailler sur IQueryable<T> peut dans de nombreux cas vous éviter de retourner trop de lignes depuis la base de données. Un autre exemple typique est la pagination : si vous utilisez Take et Skip sur IQueryable, vous n’obtiendrez que le nombre de lignes demandées ; faire cela sur un IEnumerable<T> fera charger toutes vos lignes en mémoire.