Подтвердить что ты не робот

Linq - Какой самый быстрый способ узнать отсроченное исполнение или нет?

Каков самый быстрый способ узнать, какие методы linq framework.net(например,.Inumerable linq methods) реализованы с использованием отложенного выполнения, а не с использованием отложенного выполнения.

Во время кодирования много раз, я задаюсь вопросом, будет ли это выполнено правильно. Единственный способ узнать это - перейти к документации MSDN, чтобы убедиться. Был бы какой-нибудь более быстрый способ, любой каталог, любой список где-то в Интернете, любой чит-лист, любой другой трюк в рукаве, который вы можете поделиться? Если да, сделайте это. Это поможет многим linq noobs (как я) сделать меньше ошибок. Единственный другой вариант - проверить документацию до тех пор, пока вы не воспользуетесь им достаточно, чтобы помнить (что для меня сложно, я не помню "ничего", которое где-то задокументировано и может быть просмотрено: D).

4b9b3361

Ответ 1

Обычно методы, возвращающие последовательность, используют отложенное выполнение:

IEnumerable<X> ---> Select ---> IEnumerable<Y>

и методы, возвращающие один объект, не выполняются:

IEnumerable<X> ---> First ---> Y

Итак, методы типа Where, Select, Take, Skip, GroupBy и OrderBy используют отложенное выполнение, поскольку они могут, в то время как такие методы, как First, Single, ToList и ToArray не потому, что они не могут.

Существует также два типа отложенного исполнения. Например, метод Select получит только один элемент за раз, когда он попросил создать элемент, тогда как метод OrderBy должен будет потреблять весь источник, когда его попросят вернуть первый элемент. Итак, если вы привязаете OrderBy после Select, выполнение будет отложено до получения первого элемента, но затем OrderBy запросит Select для всех элементов.

Ответ 2

Рекомендации, которые я использую:

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

  • Если вы просматриваете перечисление, всегда показывайте его как коллекцию (ICollection<T> или IList<T>), если это обычно используются вашими клиентами. Например, уровень доступа к данным часто возвращает коллекцию объектов домена. Показывать только IEnumerable<T>, если отложенное выполнение является разумным вариантом для API, который вы публикуете.

Ответ 3

Собственно, там больше; кроме того, вам нужно учитывать буферизацию и небуферизацию. OrderBy может быть отсрочен, но когда итерация должна потреблять весь поток.

В общем, что-либо в LINQ, которое возвращает IEnumerable, как правило, откладывается - в то время как Min и т.д. (возвращающие значения) не откладываются. Буферизация (vs not) обычно может быть аргументирована, но откровенно отражатель - довольно быстрый способ узнать наверняка. Но обратите внимание, что часто это все-таки информация о реализации.

Ответ 4

Для фактического "отложенного выполнения" вам нужны методы, которые работают с IQueryable. Цепи методов, основанные на работе IQueryable, для построения дерева выражений, представляющего ваш запрос. Только когда вы вызываете метод, который принимает IQueryable и выдает конкретный или IEnumerable результат (ToList() и аналогичный, AsEnumerable() и т.д.), Это дерево, оцениваемое поставщиком Linq (Linq2Objects встроен в Framework, как Linq2SQL и теперь MSEF, другие ORM и структуры уровня persistence-уровня также предлагают провайдеры Linq), и возвращается фактический результат. Любой класс IEnumerable в структуре может быть передан в IQueryable с использованием метода расширения AsQueryable(), а поставщики Linq, которые будут транслировать дерево выражений, например ORM, предоставят AsQueryable() в качестве точки перехода для запроса linq против их данные.

Даже против IEnumerable некоторые из методов Linq являются "ленивыми". Поскольку красота IEnumerable заключается в том, что вам не нужно знать обо всем этом, только текущий элемент и есть ли другие методы Linq, которые действуют на IEnumerable, часто возвращают класс итератора, который выплескивает объект из его источника всякий раз методы позже в цепочке просят об этом. Любая операция, которая не требует знания всего набора, может быть лениво оценена (выберите и где два больших, есть другие). Которые требуют знания всей коллекции (сортировка с помощью OrderBy, группировка с GroupBy и агрегаты, такие как Min и Max), будут обрабатывать весь свой источник, перечислимый в список или массив, и работать над ним, заставляя оценивать все элементы через все более высокие узлы. Как правило, вы хотите, чтобы они опоздали в цепочке методов, если вы можете помочь.

Ответ 6

Вот краткое описание различных способов узнать, будет ли ваш запрос отложен или нет:

  1. Если вы используете синтаксис выражения запроса вместо синтаксиса метода запроса, то он будет отложен.

  2. Если вы используете синтаксис метода запроса, он МОЖЕТ быть отложен в зависимости от того, что он возвращает.

  3. Наведите курсор на ключевое слово var (если это то, что вы используете в качестве типа для переменной, используемой для хранения запроса). Если он говорит IEnumerable<T> то он будет отложен.

  4. Попробуйте перебрать запрос, используя foreach. Если вы получаете сообщение об ошибке, в котором говорится, что он не может перебрать вашу переменную, поскольку он не поддерживает GetEnumerator(), вы знаете, что запрос не откладывается.

Источник: Essential Linq

Ответ 7

Если вы передали коллекцию в IQueryable с использованием .AsQueryable(), ваши вызовы LINQ будут использовать отложенное выполнение.

Смотрите здесь: Использование IQueryable с Linq