Зачем использовать AsQueryable () вместо List ()? - PullRequest
55 голосов
/ 10 июля 2009

Я использую шаблон репозитория для доступа к данным с Entity Framework и LINQ в качестве основы реализации не тестового репозитория. Большинство примеров, которые я вижу, возвращают AsQueryable (), когда вызов возвращает N записей вместо List . В чем преимущество этого?

Ответы [ 4 ]

88 голосов
/ 10 июля 2009

AsQueryable просто создает запрос, инструкции, необходимые для получения списка. Позже вы можете внести дополнительные изменения в запрос, такие как добавление новых предложений Where, которые отправляются полностью до уровня базы данных.

AsList возвращает фактический список со всеми элементами в памяти. Если вы добавите новую подсказку «Где», вы не сможете быстро фильтровать базу данных. Вместо этого вы получаете всю информацию в списке, а затем отфильтровываете то, что вам не нужно в приложении.

Так что в основном все сводится к ожиданию до последнего возможного момента, прежде чем совершить себя.

23 голосов
/ 10 июля 2009

Возвращение IQueryable<T> имеет преимущество в том, что выполнение является отложенным до тех пор, пока вы действительно не начнете перечислять результат, и вы сможете скомпоновать запрос с другими запросами и все же получить выполнение на стороне сервера.

Проблема в том, что вы не можете контролировать время жизни контекста базы данных в этом методе - вам нужен открытый контекст и вы должны убедиться, что он остается открытым до тех пор, пока не будет выполнен запрос. И тогда вы должны убедиться, что контекст будет ликвидирован. Если вы возвращаете результат как List<T>, T[] или что-то подобное, вы теряете отложенное выполнение и выполнение составленных запросов на стороне сервера, но вы получаете контроль над временем жизни контекста базы данных.

Что подходит лучше всего, конечно, зависит от фактических требований. Это другой вопрос без единой правды.

11 голосов
/ 04 ноября 2010

AsQueryable - это метод расширения для IEnumerable<T>, который может делать две вещи:

  • Если IEnumerable<T> реализует IQueryable<T> оправдывает приведение, ничего не делая.
  • В противном случае создает «фальшивку» IEnumerable<T> (EnumerableQuery<T>), которая реализует каждый метод, компилирующий лямбда-выражения и вызывающий методы расширения Enumerable.

Так что в большинстве случаев использование AsQueryable бесполезно, если только вы не вынуждены передавать IQueryable методу и вместо этого у вас есть IEnumerable, это взлом.

ПРИМЕЧАНИЕ. AsQueryable - это взлом, а IQueryable - нет!

4 голосов
/ 10 июля 2009

Возвращение IQueryable<T> будет откладывать выполнение запроса до фактического использования его результатов. До этого вы также можете выполнять дополнительные операции с запросами к базе данных на IQueryable<T>; на List вы ограничены, как правило, менее эффективными операциями в памяти.

...