Quel est le but de AsQueryable ()?

AsQueryable() -t-il simplement pour but de transmettre un IEnumerable à des méthodes susceptibles d’attendre IQueryable , ou existe-t-il une raison utile pour représenter IEnumerable tant que IQueryable ? Par exemple, est-il supposé être pour des cas comme celui-ci:

 IEnumerable orders = orderRepo.GetAll(); // I don't want to create another method that works on IEnumerable, // so I convert it here. CountOrders(orders.AsQueryable()); public static int CountOrders(IQueryable ordersQuery) { return ordersQuery.Count(); } 

Ou fait-il réellement faire quelque chose de différent:

 IEnumerable orders = orderRepo.GetAll(); IQueryable ordersQuery = orders.AsQueryable(); IEnumerable filteredOrders = orders.Where(o => o.CustomerId == 3); IQueryable filteredOrdersQuery = ordersQuery.Where(o => o.CustomerId == 3); // Are these executed in a different way? int result1 = filteredOrders.Count(); int result2 = filteredOrdersQuery.Count(); 

Les versions IQueryable de ces méthodes d’extension ne font-elles que construire une expression qui finit par faire la même chose une fois exécutée? Ma principale question est la AsQueryable : AsQueryable cas réel d’utilisation d’ AsQueryable ?

Il y a quelques utilisations principales.

  1. Comme mentionné dans d’autres réponses, vous pouvez l’utiliser pour simuler une source de données interrogeable en utilisant une source de données en mémoire afin de pouvoir tester plus facilement des méthodes qui seront éventuellement utilisées sur un IQueryable non énumérable.

  2. Vous pouvez écrire des méthodes d’assistance pour manipuler des collections pouvant s’appliquer à des séquences en mémoire ou à des sources de données externes. Si vous écrivez vos méthodes d’aide pour utiliser entièrement IQueryable vous pouvez simplement utiliser AsQueryable sur tous les énumérables pour les utiliser. Cela vous permet d’éviter d’écrire deux versions distinctes de méthodes d’assistance très généralisées.

  3. Il vous permet de modifier le type de compilation d’un interrogable pour qu’il devienne un type IQueryable plutôt qu’un type plus dérivé. En effet; vous l’utiliseriez sur un IQueryable au même moment que vous utiliseriez AsEnumerable sur un IEnumerable . Vous pouvez avoir un object qui implémente IQueryable mais qui a également une méthode Select instance. Si tel était le cas, et que vous souhaitiez utiliser la méthode LINQ Select , vous devez remplacer le type de compilation de l’object par IQueryable . Vous pouvez simplement le lancer, mais en ayant une méthode AsQueryable , vous pouvez tirer parti de l’inférence de type. Ceci est simplement plus pratique si la liste d’arguments génériques est complexe et qu’elle est nécessaire si l’un des arguments génériques est de type anonyme.

Le cas le plus valable que j’ai pour AsQueryable est le test unitaire. Dis que j’ai l’exemple suivant un peu artificiel

 public interface IWidgetRepository { IQueryable Resortingeve(); } public class WidgetController { public IWidgetRepository WidgetRepository {get; set;} public IQueryable Get() { return WidgetRepository.Resortingeve(); } } 

et je veux écrire un test unitaire pour vérifier que le contrôleur renvoie les résultats renvoyés par le référentiel. Cela ressemblerait à ceci:

 [TestMethod] public void VerifyRepositoryOutputIsReturned() { var widget1 = new Widget(); var widget2 = new Widget(); var listOfWidgets = new List() {widget1, widget2}; var widgetRepository = new Mock(); widgetRepository.Setup(r => r.Resortingeve()) .Returns(listOfWidgets.AsQueryable()); var controller = new WidgetController(); controller.WidgetRepository = widgetRepository.Object; var results = controller.Get(); Assert.AreEqual(2, results.Count()); Assert.IsTrue(results.Contains(widget1)); Assert.IsTrue(results.Contains(widget2)); } 

où vraiment, toute la méthode AsQueryable () me permet de satisfaire le compilateur lors de la configuration d’un simulacre.

Je serais intéressé quand cela est utilisé dans le code de l’application si.

Comme l’a noté sanjuro, le but de AsQueryable () est expliqué dans Utilisation de AsQueryable avec Linq To Objects et Linq To SQL . En particulier, l’article stipule que

Cela offre d’excellents avantages dans les scénarios de mots réels où vous avez certaines méthodes sur une entité qui renvoient un IQueryable de T et certaines méthodes renvoient List. Cependant, vous devez appliquer un filtre de règles métier à toute la collection, même si la collection est renvoyée sous la forme IQueryable de T ou IEnumerable de T. Du sharepoint vue des performances, vous souhaitez vraiment exécuter le filtre métier sur la firebase database. la collection implémente IQueryable sinon, retombe en appliquant le filtre métier en mémoire à l’aide de Linq pour objecter l’implémentation des delegates.

Interface IQueryable citant la documentation:

L’interface IQueryable est destinée à être implémentée par les fournisseurs de requêtes.

Ainsi, pour quelqu’un qui a l’intention de rendre son dataset interrogeable dans .NET, cette structure de données non nécessaire peut être énumérée ou comporter un énumérateur valide .

IEnumerator est une interface pour l’itération et le traitement des stream de données à la place.

Le but de AsQueryable () est grandement expliqué dans cet article Utilisation de AsQueryable avec Linq To Objects et Linq To SQL

Dans la section Notes de la méthode MSDN Queryable.AsQueryable:

Si le type de source implémente IQueryable, AsQueryable (IEnumerable) le renvoie directement. Sinon, il renvoie un object IQueryable qui exécute des requêtes en appelant les méthodes d’opérateur de requête équivalentes dans Enumerable au lieu de celles de Queryable.

C’est exactement ce qui est mentionné et utilisé dans l’article ci-dessus. Dans votre exemple, cela dépend de ce que retourne orderRepo.GetAll, IEnumerable ou IQueryable (Linq to Sql). Si elle retourne IQueryable, la méthode Count () sera exécutée sur la firebase database, sinon elle sera exécutée en mémoire. Regardez attentivement l’exemple dans l’article référencé.