Какова цель AsQueryable()?
цель AsQueryable() просто так вы можете пройти вокруг IEnumerable к методам, которые могут ожидать IQueryable, или есть полезная причина для представления IEnumerable как IQueryable? Например, это должно быть для таких случаев:
IEnumerable<Order> 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<Order> ordersQuery)
{
return ordersQuery.Count();
}
или это действительно заставляет его делать что-то другое:
IEnumerable<Order> orders = orderRepo.GetAll();
IQueryable<Order> ordersQuery = orders.AsQueryable();
IEnumerable<Order> filteredOrders = orders.Where(o => o.CustomerId == 3);
IQueryable<Order> filteredOrdersQuery = ordersQuery.Where(o => o.CustomerId == 3);
// Are these executed in a different way?
int result1 = filteredOrders.Count();
int result2 = filteredOrdersQuery.Count();
сделать IQueryable версии этих методов расширения просто создают выражение, которое в конечном итоге делает то же самое после его выполнения? Мой главный вопрос, что такое реальный случай использования для использования AsQueryable?
5 ответов:
есть несколько основных целей.
как упоминалось в других ответах, вы можете использовать его для макета запрашиваемого источника данных с использованием источника данных в памяти, чтобы вы могли более легко тестировать методы, которые в конечном итоге будут использоваться на неисчислимой основе
IQueryable.вы можете написать вспомогательные методы для управления коллекциями, которые могут применяться как к последовательностям в памяти, так и к внешним источникам данных. Если вы пишете свои методы помощи для использования
IQueryableполностью вы можете просто использоватьAsQueryableна всех перечисляемых использовать их. Это позволяет избежать написания двух отдельных версий очень обобщенных вспомогательных методов.это позволяет вам изменить тип времени компиляции запроса, чтобы быть
IQueryable, а не какой-то более производный тип. В сущности, вы бы использовали его наIQueryableв то же время, что вы бы использоватьAsEnumerableнаIEnumerable. У вас может быть объект, который реализуетIQueryableно у этого также есть экземплярSelectметод. Если бы это было так, и вы хотели использовать LINQSelectметод, вам нужно будет изменить тип времени компиляции объекта наIQueryable. Вы могли бы просто бросить его, но имеяAsQueryableметод вы можете воспользоваться типом вывода. Это просто удобнее, если общий список аргументов является сложным, и это на самом деле необходимые если какой-либо из общих аргументов является анонимным типом.
наиболее допустимым случаем, который я имею для AsQueryable, является модульное тестирование. Скажем, у меня есть следующий несколько надуманный пример
public interface IWidgetRepository { IQueryable<Widget> Retrieve(); } public class WidgetController { public IWidgetRepository WidgetRepository {get; set;} public IQueryable<Widget> Get() { return WidgetRepository.Retrieve(); } }и я хочу написать unit-тест, чтобы убедиться, что контроллер возвращает результатов, возвращаемых из хранилища. Это будет выглядеть примерно так:
[TestMethod] public void VerifyRepositoryOutputIsReturned() { var widget1 = new Widget(); var widget2 = new Widget(); var listOfWidgets = new List<Widget>() {widget1, widget2}; var widgetRepository = new Mock<IWidgetRepository>(); widgetRepository.Setup(r => r.Retrieve()) .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)); }где, действительно, все AsQueryable() метод позволяет мне сделать, это удовлетворить компилятор при создании макета.
мне было бы интересно, где это используется в приложении хотя код.
Как отметил сандзюро, цель AsQueryable () объясняется в использование AsQueryable с Linq to Objects и Linq to SQL. В частности, в статье говорится,
Это дает отличные преимущества в реальных сценариях word, где у вас есть определенные методы на сущности, которые возвращают IQueryable из T и некоторые методы возвращают список. Но тогда у вас есть фильтр бизнес-правил, который должен применяться ко всей коллекции независимо от того, возвращается ли коллекция как IQueryable из T или IEnumerable из T. С точки зрения производительности вы действительно хотите использовать выполнение бизнес-фильтра в базе данных, если коллекция реализует IQueryable в противном случае отступает, чтобы применить бизнес-фильтр в памяти с помощью Linq для реализации объектов делегатов.
интерфейс
IQueryableцитирую документацию:интерфейс IQueryable предназначен для реализации запросом услуги поставщиков.
Итак, для кого-то, кто намерен сделать свою datastracture queryable в .NET, эта datastructure что не обязательно может быть перечислено или иметь действительный перечислитель.
IEnumerator- это интерфейс для перебора и обработки поток данных вместо.
цель AsQueryable () очень подробно объясняется в этой статье использование AsQueryable с Linq to Objects и Linq to SQL
в разделе "Примечания" доступна на MSDN.Способ AsQueryable:
Если тип источника реализует IQueryable, AsQueryable (IEnumerable) возвращает его напрямую. В противном случае он возвращает IQueryable, который выполняет запросы, вызывая эквивалентные методы оператора запроса в Enumerable вместо методов in Вопросительный.
Это именно то, что упоминается и используется в вышеуказанной статье. В вашем примере это зависит от того, что такое orderRepo.GetAll returning, IEnumerable или IQueryable (Linq to Sql). Если он возвращает IQueryable, метод Count () будет выполняться в базе данных, иначе он будет выполняться в памяти. Посмотрите внимательно на пример в ссылочной статье.
Comments