Зачем использовать AsQueryable () вместо List ()?

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

 Mattias Nordqvist18 апр. 2013 г., 22:58
Что такое не тестовый репозиторий?

Ответы на вопрос(4)

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

 10 июл. 2009 г., 00:48
Я думаю, это то, что уже сказал Грауэнольф: P :)
 10 июл. 2009 г., 04:07
Его ответ был представлен, пока я писал свой. :)
Решение Вопроса

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

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

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

 10 июл. 2009 г., 00:45
согласитесь, но помните, что помимо «быстрой фильтрации», существует также возможность отправки всей этой информации через сеть.
 10 июл. 2009 г., 00:47
Кроме того, это не единственный способ сделать это, так как вы можете получить фильтры для применения вместо того, чтобы возвращать что-то, что можно отфильтровать. Первый проще в использовании, если позже вы перейдете от использования базы данных к чему-то другому, то есть к веб-службе или чему-то еще.
 10 июл. 2009 г., 01:09
Еще один момент: если вы возвращаете IQueryable, вы должны найти хороший способ убедиться, что 1.) контекст открыт до тех пор, пока запрос не будет выполнен, и 2.) контекст будет корректно удален. Возвращение списка имеет то преимущество, что вы можете контролировать время жизни контекста внутри метода. Что подходит лучше, зависит от фактических требований.
 07 авг. 2018 г., 05:51
@JoeBrockhaus что делать, если вы используетеGetMyEntities<T> (Expression<Func<<bool,T>> pred) вместоGetMyEntities<T>(Func<bool,T> pred)?
 04 мар. 2015 г., 21:32
WRT @eglasius Вы можете очень легко использовать предикат в качестве параметра метода репозитория, такого какpublic GetMyEntities<T> (Func<bool,T> pred) или жеpublic GetMyEntities<MyEntity> (Func<bool,MyEntity> pred) а затем добавить это к запросу, какreturn context.MyEntities.Where(pred).ToList();, Сначала вы должны убедиться, что оно не равно нулю, но вы поняли идею. Затем, когда вы используете его, вы можете применить предикат в вызове, а не после: `repo.GetMyEntities (x = & gt; x.ThatProperty == false) & apos ;. Это может повысить вероятность того, что несовместимые с Linq2Sql методы вызовут исключения, но у каждого есть tradeofs

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

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

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

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

If the IEnumerable<T> implements IQueryable<T> justs casts, doing nothing. Otherwise creates a 'fake' IEnumerable<T> (EnumerableQuery<T>) that implements every method compiling the lambdas and calling to Enumerable extension methods.

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

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

 10 февр. 2018 г., 00:57
IQueryable и AsQueryable просто спасли мне жизнь
 06 сент. 2011 г., 06:58
AsQueryable не бесполезен, так как вы указываете, что «прецедент использования» принудительно передается как IQueryable & quot; является допустимым, он позволяет вам использовать то, что предлагает IQueryable, и это больше, чем IEnumerable. Я бы не считал это хаком, и он имеет свои применения, см., Например, здесь:wcf.codeplex.com/… , Но я предполагаю, что вы хотите сказать, что его нельзя использовать, чтобы углубиться и повлиять на то, как создаются Enumerable данные (например, оптимизировать запрос), он будет работать только поверх того, что было создано / получено.

Ваш ответ на вопрос