Что является самым сложным или наиболее неправильно понятым аспектом LINQ?

Предыстория: В течение следующего месяца я проведу три доклада о LINQ или, по крайней мере, о его включении в контекст C#. Я хотел бы знать, каким темам стоит уделить изрядное внимание, исходя из того, что людям может быть трудно понять, или из-за чего у них может сложиться ошибочное впечатление. Я не буду специально говорить о LINQ, SQL или Entity Framework, за исключением примеров того, как запросы могут выполняться удаленно с использованием деревьев выражений (и обычно IQueryable).

Итак, что вы нашли сложным в LINQ? Что вы видели в плане недопонимания? Примеры могут быть любыми из следующих, но, пожалуйста, не ограничивайте себя!

  • Как компилятор C# обрабатывает выражения запроса
  • Лямбда-выражения
  • Деревья выражений
  • Методы расширения
  • Анонимные типы
  • IQueryable
  • Отложенное или немедленное исполнение
  • Потоковое или буферизованное исполнение (например, OrderBy откладывается, но буферизуется)
  • Неявно типизированные локальные переменные
  • Чтение сложных общих подписей (например, Enumerable.Join)

Мне было бы интересно узнать, когда вы собираетесь провести эти переговоры, и есть ли способ просмотреть их в Интернете.

Mark Heath 20.10.2008 00:24

Первый разговор: Копенгаген, 30 октября. Надеюсь, это будет записано на пленку. (Целый день!) Вторая беседа: Лондон, 19 ноября вечером, Лондонская группа пользователей .NET, вероятно, на Push LINQ. Третий доклад: чтение, 22 ноября, День разработчиков, реализация LINQ to Objects за 60 минут.

Jon Skeet 20.10.2008 00:34

круто, я могу посмотреть, смогу ли я провести DDD-день в Ридинге

Mark Heath 20.10.2008 00:51

Голосующие против: пожалуйста, добавьте пояснительный комментарий.

Jon Skeet 19.05.2009 09:14

@Jon, извини, но мне нужно закрыть это.

Tim Post 20.08.2011 22:27

@ Тим: Достаточно честно - он все равно больше не получал ответов. Лично я думаю, что сделал в конечном итоге будет конструктивным, заметьте - мне определенно было полезно увидеть, что люди находят сложным. Я бы, наверное, не стал спрашивать об этом сейчас ...

Jon Skeet 20.08.2011 22:33

@Jon - я могу изменить его на «слишком локализованный», если хотите. У меня есть перечисленный список, из которого я выбрал тот, который, на мой взгляд, подходит лучше всего. Я уверен, что этот вопрос будет иметь значение для других, просто он не относится к теме переполнения стека, появившейся почти через три года после того, как вы задали этот вопрос.

Tim Post 20.08.2011 23:40

@ Тим: Совершенно верно. Возможно, стоит вместо этого перейти на Программисты? Речь идет о программистах как людях ... но также о конкретной технологии, что делает ее сложной. Честно говоря, я не такой уж разборчивый.

Jon Skeet 20.08.2011 23:47

@Jon У него довольно много ответов (один принят), ему почти три года, и перенос его на другой сайт был бы не очень конструктивным. Я не совсем уверен, как можно улучшить систему на основе этого опыта. Или, скорее, я не могу сформулировать какие-либо предлагаемые улучшения.

Tim Post 21.08.2011 00:06

@Tim: Может быть, по поводу меты спросить мнения? Или прямо к Джеффу? Я не знаю, насколько это распространено.

Jon Skeet 21.08.2011 00:18

@Jon, это угловые случаи, которые действительно следует рассмотреть, я предлагаю мета. Помните, письмо Джеффа ненавидит. Прикосновение к подобному вопросу вызывает чувство трепета у всех нас [модераторов], поэтому консенсус был бы чрезвычайно полезен.

Tim Post 21.08.2011 00:25
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
282
11
49 712
42
Перейти к ответу Данный вопрос помечен как решенный

Ответы 42

Ленивая загрузка.

Pratik 07.10.2011 19:57
Ответ принят как подходящий

Отсроченное исполнение

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

Jon Skeet 25.10.2008 23:51

Действительно? Во время изучения Linq мне так много раз указывали на его ленивую природу, что для меня это никогда не было проблемой.

Adam Lassek 17.12.2008 19:19

@ALassek, это действительно зависит от того, где вы изучаете LINQ. Я представил для групп пользователей, где никто не знал, чем лениво оценили.

JaredPar 18.12.2008 02:44

Согласен с ALassek. В документации MSDN четко указано, что LINQ выполняет ленивую оценку. Может быть, настоящая проблема в ленивом программировании разработчиков ... =)

Seiti 18.12.2008 21:30

... особенно когда вы понимаете, что он применяется к LINQ к объектам, а не только к LINQ 2 SQL - когда вы видите 10 вызовов веб-методов для получения списка элементов, когда вы уже перечисляете тот же список элементов, и вы подумали, что список уже был оценен

Simon_Weaver 15.02.2009 08:26

Это должно быть отложенное исполнение, верно? Андерс много раз упоминал об этом в своих видеороликах о LINQ на канале MSDN Channel 9.

Eriawan Kusumawardhono 03.03.2009 07:14

@eriawan, отложенные или отложенные работы :)

JaredPar 03.03.2009 07:33

Знание того, что такое оператор yield и как он работает, IMHO критически важно для полного понимания LINQ.

peSHIr 06.03.2009 10:43

У меня есть коллеги, которые, даже если мне миллионы раз говорили или после прочтения книги в книге, все равно не получают ленивое поведение LINQ при выполнении.

Pauli Østerø 14.12.2010 02:29

Кажется, распространено заблуждение, что IEnumerable - это ленивый список, то есть оценивается только один раз.

Robert Jeppesen 18.03.2011 00:31

Что есть больше, чем просто LINQ - SQL, и функции - это больше, чем просто синтаксический анализатор SQL, встроенный в язык.

Мне надоело, что все думают, что: /

TraumaPony 19.10.2008 05:09

Не все делают! Я до сих пор не знаю, что такое LINQ to SQL, и постоянно использую LINQ.

Robert Rossney 19.10.2008 22:55

Меня так раздражает, когда я пытаюсь что-то объяснить с помощью LINQ, а другой человек просто смотрит на меня и говорит: «Ооо, я не использую LINQ ни для чего подобного, только SQL» :(

Nathan W 28.10.2008 15:54

Согласен, многие люди, похоже, не понимают, что LINQ - это инструмент общего назначения.

Matthew Olenik 07.03.2009 07:41

Я думаю, что тот факт, что выражение Lambda может разрешаться как в дерево выражений, так и в анонимный делегат, поэтому вы можете передать одно и то же декларативное выражение lambda как методам расширения IEnumerable<T>, так и методам расширения IQueryable<T>.

Согласовано. Я ветеран, и я только что понял, что это неявное приведение происходит, когда начал писать свой собственный QueryProvider.

TheSoftwareJedi 31.05.2009 20:31

Я думаю, вам следует уделять больше внимания наиболее часто используемым функциям LINQ в деталях - лямбда-выражениям и анонимным типам, а не тратить время на «трудные для понимания» вещи, которые редко используются в реальных программах.

Я согласен с принципом, но на самом деле почти все трудные для понимания биты являются часто используются в реальных программах - просто люди не понимают их.

Jon Skeet 19.10.2008 10:37

У меня все еще есть проблемы с командой "let" (которой я никогда не находил применения) и SelectMany (которую я использовал, но не уверен, что сделал это правильно)

Каждый раз, когда вы хотите ввести переменную, вы должны использовать оператор let. Подумайте о традиционном цикле, в котором вы вводите в него переменные и даете каждой переменной имя, чтобы облегчить читаемость кода. Иногда также хорошо, когда у вас есть оператор let, оценивающий результат функции, который вы затем можете выбрать и упорядочить, не оценивая результат дважды.

Rob Packwood 05.03.2010 01:23

'let' позволяет создавать составные типы. Удобная штука.

Phill 31.12.2010 16:20

В LINQ to SQL я постоянно вижу людей, не понимающих DataContext, как его можно использовать и как его следует использовать. Слишком много людей не видят DataContext таким, какой он есть - объектом Unit of Work, а не постоянным объектом.

Я видел много раз, когда люди пытались выделить DataContext / session it / etc вместо того, чтобы создавать новое время для каждой операции.

И затем следует избавиться от DataContext до того, как IQueryable будет оценен, но это больше касается людей, не понимающих IQueryable, чем DataContext.

Другая концепция, с которой я вижу много путаницы, - это синтаксис запросов и синтаксис выражений. Я буду использовать самый простой вариант, часто придерживаясь синтаксиса выражений. Многие люди до сих пор не понимают, что в конечном итоге они получат то же самое. В конце концов, Query компилируется в Expression.

Предупреждение: Единицей работы может быть небольшая программа с контекстом данных как синглтоном.

graffic 29.11.2008 17:16

Вы не должны использовать DataContext в синглтоне, это не потокобезопасный.

Aaron Powell 30.11.2008 07:56

@Slace, не все программы являются многоголовыми, поэтому можно использовать DataContext в качестве синглтона во многих "настольных" программах.

Ian Ringrose 04.11.2009 19:16

Меня это укусило (используя DataContext как одноэлемент), когда я делал свой первый проект LINQ to SQL. Я не думаю, что документация и книги делают это достаточно очевидным. На самом деле, я думаю, что название можно было бы улучшить, но я не знаю, как это сделать.

Roger Lipscombe 09.04.2010 10:59

Мне потребовалось несколько раз прочитать статьи ScottY о Linq, чтобы эта мысль пришла мне в голову.

Evan Plaice 15.06.2010 00:49

Понимание того, когда происходит утечка абстракции между поставщиками Linq. Некоторые вещи работают с объектами, но не с SQL (например, .TakeWhile). Некоторые методы могут быть переведены в SQL (ToUpper), а другие - нет. Некоторые методы более эффективны в объектах, тогда как другие более эффективны в SQL (различные методы соединения).

Это очень хороший момент. Не помогает то, что Intellisense покажет вам ВСЕ их, и обычно даже компилируется. Тогда вы взорветесь во время выполнения. Я надеюсь, что VS 2010 лучше показывает соответствующие методы расширения.

Jason Short 23.08.2009 04:41

Я, например, хотел бы знать, нужно ли мне знать, что такое деревья выражений и почему.

Я думаю, что стоит знать, что такое деревья выражений и почему они существуют, но не знать подробностей о том, как их построить самостоятельно. (Их сложно собрать вручную, но компилятор отлично справится с преобразованием лямбда-выражения.)

Jon Skeet 19.10.2008 10:39

На самом деле, я думал о том, чтобы сделать несколько записей в блоге о деревьях выражений (поскольку я их «понимаю»). Я считаю очень полезным манипулирование деревьями выражений ...

Marc Gravell 19.10.2008 14:03

Однако я не думаю, что они будут полезны для разговоров Джона ;-p

Marc Gravell 19.10.2008 14:04

Мне нужно упомянуть их вкратце, но ваши записи в блоге, безусловно, будут приветствоваться :)

Jon Skeet 19.10.2008 21:36

Я просто беспокоюсь, что деревья выражений будут похожи на оператор yield: что-то, что оказалось невероятно ценным, несмотря на то, что я сначала не понимал, для чего это было.

Robert Rossney 19.10.2008 22:54

Марк Грейвелл. Я хотел бы прочитать ваши записи в блоге по этой теме. С нетерпением жду этого

Alexandre Brisebois 20.10.2008 03:06

Я добавил в эту цепочку пост со ссылкой ...

Marc Gravell 20.10.2008 13:09

Я новичок в LINQ. Вот то, о чем я споткнулся с первой попытки

  • Объединение нескольких запросов в один
  • Эффективная отладка запросов LINQ в Visual Studio.

Отладка LINQ - это отдельная тема, очень важная. Я думаю, что самая большая слабость LINQ заключается в том, что он позволяет вам писать блоки произвольно сложной логики, которые вы не можете пройти.

Robert Rossney 19.10.2008 22:58

это может быть хорошее место для использования LINQ pad

Maslow 03.07.2009 22:54

От всей души согласен; вот почему я написал Раскрытие секретов LINQ: связывание и отладка, только что опубликованный на Simple-Talk.com, чтобы вы могли найти помощь.

Michael Sorens 10.12.2010 19:33

Да, LinqPad - отличный вторичный инструмент для разработки ваших запросов LINQ. Особенно, если вы только начинаете, и вы новичок в соглашениях / шаблонах.

Buffalo 12.12.2010 02:14

Хорошо, из-за спроса я написал кое-что из Expression. Я не на 100% доволен тем, как blogger и LiveWriter сговорились отформатировать его, но пока этого достаточно ...

В любом случае, начнем ... Я бы хотел получить обратную связь, особенно если есть области, где людям нужна дополнительная информация.

Вот, нравится это или нет ...

Пара вещей.

  1. Люди думают о Linq как о Linq to SQL.
  2. Некоторые люди думают, что они могут начать замену всей логики / foreach запросами Linq, не учитывая это влияние на производительность.

Что быстрее, встроенное Linq-to-Sql или Linq-to-Sql с использованием Tsql Sprocs

... и есть ли случаи, когда лучше использовать запросы на стороне сервера (Sproc) или на стороне клиента (встроенный Linq).

Что представляет var при выполнении запроса?

Это iQueryable, iSingleResult, iMultipleResult, или он меняется в зависимости от реализации. Есть некоторые предположения об использовании (что кажется) динамической типизации по сравнению со стандартной статической типизацией в C#.

AFAIK var всегда является конкретным рассматриваемым классом (даже если это анонимный тип), поэтому это никогда IQueryable, ISingleResult или что-либо, начинающееся с «I» (конкретные классы, начинающиеся с «I», не должны применяться).

Motti 09.12.2008 10:25

Понимание синтаксиса «магия». Как синтаксис понимания переводится в вызовы методов и какие вызовы методов выбираются.

Как, например:

from a in b
from c in d
where a > c
select new { a, c }

переводится в вызовы методов.

Я немного рассказал об этом в своем выступлении, но в основном просто «это Сортировать того, что делает компилятор» - включая «он не знает, что перевод вызовет методы расширения и т. д.». Детали, конечно, довольно сложные ...

Jon Skeet 04.11.2008 18:26

(Тем не менее, я добавил немного о прозрачных идентификаторах, что имеет отношение к вашему примеру.)

Jon Skeet 04.11.2008 18:27

Мне всегда легче понять, если я попытаюсь переосмыслить это как цепочку методов: b.SelectMany (a => d, (a, c) => new {a = a, c = c}). Where (thing = > thing.a> thing.c) .Select (otherthing => new {a = otherthing.a, c = otherthing.c})

JerKimball 02.03.2010 22:29

group by до сих пор кружит голову.

Любую путаницу в отношении отсроченное исполнение можно разрешить путем пошагового выполнения некоторого простого кода на основе LINQ и игры в окне наблюдения.

Я обнаружил, что реализация небольшого количества LINQ to Objects для развлечения действительно помогает :) Но да, это немного сбивает с толку - конечно, если я какое-то время не использовал LINQ, мне нужно вернуться к подписям. Точно так же «присоединиться» к «присоединиться к» часто заставляет меня ...

Jon Skeet 26.11.2008 20:17

Для LINQ2SQL: ознакомьтесь с некоторыми из сгенерированных SQL и напишите запросы LINQ, которые преобразуются в хороший (быстрый) SQL. Это часть более серьезной проблемы, связанной с пониманием того, как сбалансировать декларативный характер запросов LINQ с реализмом, необходимым для быстрого их выполнения в известной среде (SQL Server).

Вы можете получить совершенно другой сгенерированный SQL-запрос, изменив крошечный элемент в коде LINQ. Это может быть особенно опасно, если вы создаете дерево выражений на основе условных операторов (т.е. добавляете дополнительные критерии фильтрации).

Первоначально я не осознавал, что синтаксис LINQ не требует для работы IEnumerable<T> или IQueryable<T>, а LINQ - это всего лишь сопоставление с образцом.

альтернативный текст http://bartdesmet.info/images_wlw/QIsIQueryabletheRightChoiceforMe_13478/image_thumb_3.png

Вот ответ (нет, я, не сделал, пишу этот блог, это сделал Барт Де Смет, и он один из лучших блоггеров по LINQ, которых я нашел).

Вы также можете найти этот пост в блоге интересным: msmvps.com/blogs/jon_skeet/archive/2008/02/29/…

Jon Skeet 09.12.2008 12:02

Хороший пост, Джон (я подписался на твой блог, правда, совсем недавно).

Aaron Powell 09.12.2008 12:29

Меня немного разочаровывает то, что синтаксис выражения запроса поддерживает только подмножество функций LINQ, поэтому вы не можете время от времени связывать методы расширения в цепочку. Например. метод Distinct нельзя вызвать с использованием синтаксиса выражения запроса. Чтобы использовать метод Distinct, вам необходимо вызвать метод расширения. С другой стороны, синтаксис выражения запроса во многих случаях очень удобен, так что вы тоже не хотите его пропускать.

В доклад о LINQ можно было бы включить некоторые практические рекомендации о том, когда предпочесть один синтаксис другому и как их смешивать.

Лично я рад, что синтаксис выражения запроса не включает очень много операторов. Точечная нотация хороша, когда вам нужно ее использовать, и этот баланс сохраняет C# по-прежнему малым языком разумно. Часть спецификации, содержащая выражение запроса, приятная и короткая - мне бы не хотелось иметь действительно длинный раздел.

Jon Skeet 20.12.2008 22:39

Как уже упоминалось, отложенная загрузка и отложенное выполнение

Чем LINQ to Objects и LINQ to XML (IEnumerable) отличаются от LINQ to SQL (IQueryable)

КАК для создания уровня доступа к данным, бизнес-уровня и уровня представления с LINQ на всех уровнях ... и хороший пример.

Первые два я могу сделать. Я бы не хотел пробовать третий вариант в смысле «это правильный способ» ...

Jon Skeet 07.01.2009 20:52

+1, пока вы не указали на это, я не осознавал, что LINQ-to-Objects и LINQ-to-XML были IEnumerable в отличие от LINQ-to-SQL как IQueryable, но это имеет смысл. Спасибо!

Pretzel 13.05.2010 19:57

Я не знаю, можно ли это считать неправильно понятым, но для меня это просто неизвестно.

Мне было приятно узнать о DataLoadOptions и о том, как я могу контролировать, какие таблицы объединяются, когда я делаю конкретный запрос.

Подробнее см. Здесь: MSDN: DataLoadOptions

Я думаю, что в LINQ стоит рассказать о том, как вы можете столкнуться с проблемами, связанными с производительностью. Например, использование счетчика LINQ в качестве условия цикла на самом деле неразумно.

Я бы сказал, что наиболее непонятым (или непонятным?) Аспектом LINQ являются IQueryable и настраиваемые поставщики LINQ.

Я уже некоторое время использую LINQ, чувствую себя комфортно в мире IEnumerable и могу решить большинство проблем с помощью LINQ.

Но когда я начал смотреть и читать об IQueryable, Expressions и пользовательских поставщиках linq, у меня закружилась голова. Посмотрите, как работает LINQ to SQL, если вы хотите увидеть довольно сложную логику.

Я с нетерпением жду понимания этого аспекта LINQ ...

Это, конечно, не самое сложное, это просто то, что нужно добавить в список:

ThenBy() extension method

Не глядя на его реализацию, я сначала озадачен тем, как это работает. Все прекрасно понимают, как поля сортировки, разделенные запятыми, работают в SQL, но на самом деле я скептически отношусь к тому, что ThenBy будет делать то, что я действительно хочу. Как он может «узнать», каким было предыдущее поле сортировки - похоже, это должно быть.

Я собираюсь исследовать это сейчас ...

Хитрость в том, что ThenBy является методом расширения IOrderedEnumerable (или IOrderedQueryable), а не просто IEnumerable / IQueryable. Вы можете скачать мою (очень наивную!) Реализацию со страницы моих выступлений: csharpindepth.com/Talks.aspx - см. «LINQ to Objects за 60 минут»

Jon Skeet 06.03.2009 10:10

Как говорило большинство людей, я думаю, что наиболее неправильно понимаемая часть - это предположение, что LINQ - это просто замена T-SQL. Мой менеджер, который сам был считает как гуру TSQL, не позволил нам использовать LINQ в нашем проекте и даже ненавидит MS за выпуск такой штуки !!!

Слишком много людей используют его как замену TSQL. Большинство из них никогда не слышали о плане исполнения.

erikkallen 28.05.2009 01:03

+1, потому что я согласен с вашим менеджером, по крайней мере, в том, что касается разрешения LINQ to SQL в любом проекте. LINQ to Objects - совсем другое дело.

NotMe 30.09.2010 18:26

Я думаю, что часть LINQ неправильно понятая в заключается в том, что это расширение языка, а не расширение или конструкция базы данных.

LINQ - это намного больше, чем LINQ to SQL.

Теперь, когда большинство из нас использовали LINQ в коллекциях, мы НИКОГДА не вернемся!

LINQ - единственная наиболее важная функция .NET со времен Generics в версии 2.0 и анонимных типов в версии 3.0.

А теперь, когда у нас есть Lambda, я не могу дождаться параллельного программирования!

Я бы даже назвал это более значимым, чем анонимные типы, и, возможно, даже больше, чем дженерики.

Justin Morgan 29.01.2011 00:58

Я знаю, что концепция отложенного выполнения должна быть уже внедрена в меня, но этот пример действительно помог мне понять ее на практике:

static void Linq_Deferred_Execution_Demo()
{
    List<String> items = new List<string> { "Bob", "Alice", "Trent" };

    var results = from s in items select s;

    Console.WriteLine("Before add:");
    foreach (var result in results)
    {
        Console.WriteLine(result);
    }

    items.Add("Mallory");

    //
    //  Enumerating the results again will return the new item, even
    //  though we did not re-assign the Linq expression to it!
    //

    Console.WriteLine("\nAfter add:");
    foreach (var result in results)
    {
        Console.WriteLine(result);
    }
}

Приведенный выше код возвращает следующее:

Before add:
Bob
Alice
Trent

After add:
Bob
Alice
Trent
Mallory
blogs.msdn.com/b/charlie/archive/2007/12/09/… <- я думаю, что это лучший блог, чтобы объяснить это, на мой взгляд. (далеко в 2007 году, не могу поверить, что это уже так давно)
Phill 31.12.2010 16:15

Обозначение Big O. LINQ позволяет невероятно легко писать алгоритмы O (n ^ 4), даже не осознавая этого, если вы не знаете, что делаете.

Как насчет примера?

hughdbrown 09.11.2009 17:54

Что касается примера, возможно, он имеет в виду тот факт, что предложение Select очень легко содержать много операторов Sum (), каждый из которых вызывает еще один проход по всему набору записей.

Rob Packwood 05.03.2010 01:22

На самом деле, возможно, даже стоит рассмотреть, что такое большая нотация O и почему она важна, а также несколько примеров неэффективных результирующих запросов. Я думаю, это то, что предлагал оригинальный плакат, но я подумал, что все равно упомяну об этом. - Обновлено: только что понял, что этому посту 1,5 года :-)

zcrar70 14.05.2010 17:41

Это не было бы O (n ^ x), это было бы O (xn), то есть просто O (n).

Malfist 16.11.2010 00:39

Попытка выполнить соединение без оператора соединения приведет к O (n ^ x): from i1 in range1 from i2 in range2 from i3 in range3 from i4 in range4 where i1 == i2 && i3 == i4 select new {i1, i2, i3, i4}. И я действительно видел это написанным раньше. Работает, но очень медленно.

MarkPflug 02.05.2011 23:18

Некоторые сообщения об ошибках, особенно от LINQ to SQL, могут сбивать с толку. ухмылка

Меня, как и всех, пару раз укусила отложенная казнь. Я думаю, что больше всего меня сбивает с толку поставщик запросов SQL Server и то, что вы можете и не можете с ним делать.

Я все еще поражен тем фактом, что вы не можете выполнить Sum () для столбца десятичных чисел / денег, который иногда бывает пуст. Использование DefaultIfEmpty () просто не сработает. :(

Должно быть довольно легко указать где в этом запросе, чтобы сумма работала

Esben Skov Pedersen 16.10.2009 12:30

Я уверен, что почти один знает: вы можете использовать встроенные if в запросе linq. Что-то вроде этого:

var result = from foo in bars where (
    ((foo.baz != null) ? foo.baz : false) &&
    foo.blah == "this")
    select foo;

Я полагаю, вы также можете вставлять лямбды, хотя я не пробовал.

Это просто условное выражение - почему не стал бы вы можете его использовать?

Jon Skeet 19.06.2009 11:23

У меня сложилось (вероятно, ошибочное) впечатление, что это похоже на обычное «если»: вы бы не увидели вложения таких обычных «если», не так ли? или я мог ошибаться ...

RCIX 19.06.2009 13:34

Если - это инструкция, а условный оператор - это выражение. Это разные формы одной и той же концепции ветвления. В этом случае, однако, вы можете сделать "foo.baz ?? false" и использовать нулевой оператор объединения :-)

Bryan Watts 30.07.2009 07:22

Я думаю, что больше людей знают тернарный оператор, чем противоположный ..

devoured elysium 04.01.2010 21:46

Условные выражения, приводящие к логическим значениям, могут быть сокращены до логических и / или выражений, поэтому (foo.baz != null) ? foo.baz : false эквивалентен (foo.baz != null) && foo.baz. Я думаю, что это можно применить к любому троичному выражению, которое может быть передано как условие where. Так что неудивительно, ИМХО

Justin Morgan 04.02.2011 19:44

Скомпилированные запросы

Тот факт, что вы не можете связать IQueryable, потому что они являются вызовами методов (в то время как по-прежнему не что иное, как переводимый SQL!) И что это практически невозможно обойти, это ошеломляет и создает огромное нарушение DRY. Мне нужны мои IQueryable для ad-hoc, в которых у меня нет скомпилированных запросов (я скомпилировал запросы только для тяжелых сценариев), но в скомпилированных запросах я не могу их использовать, и вместо этого мне нужно снова писать обычный синтаксис запросов. Теперь я делаю те же подзапросы в двух местах, нужно не забывать обновлять оба, если что-то изменится, и так далее. Кошмар.

Мне потребовалось слишком много времени для путь, чтобы понять, что многие методы расширения LINQ, такие как Single(), SingleOrDefault() и т. д., Имеют перегрузки, которые принимают лямбды.

Ты можешь сделать :

Single(x => x.id == id)

и не нужно этого говорить - что из-за плохого учебника я привык делать

Where(x => x.id == id).Single()

+1, очень красиво. Буду иметь в виду.

Pretzel 13.05.2010 19:53

Я тоже все время забываю об этом. Это также верно и для Count(), среди прочих. Знаете ли вы, есть ли разница в производительности помимо очевидного бонуса читаемости кода?

Justin Morgan 29.01.2011 00:57

В университете мой преподаватель хотел снять баллы за использование этих перегрузок !! Я доказал, что он неправ!

TDaver 16.02.2011 19:10

Это может показаться странным, но я предпочитаю второй синтаксис. Я считаю это более читаемым.

Konamiman 18.02.2011 19:20

Я не думаю, что все понимают, насколько легко вложить петлю.

Например:

from outerloopitem in outerloopitems
from innerloopitem in outerloopitem.childitems
select outerloopitem, innerloopitem

+1, эй. это довольно мощно.

Pretzel 13.05.2010 19:59

Как говорило большинство людей, я думаю, что наиболее неправильно понимаемая часть - это предположение, что LINQ - это просто замена T-SQL. Мой менеджер, считающий себя гуру TSQL, не позволил бы нам использовать LINQ в нашем проекте и даже ненавидит MS за выпуск такой штуки !!!

Тот факт, что вы не можете связать IQueryable, потому что они являются вызовами методов (при этом ничего другого, кроме SQL-переводимого!), И что это практически невозможно обойти, ошеломляет и создает огромное нарушение DRY. Мне нужны мои IQueryable для ad-hoc, в которых у меня нет скомпилированных запросов (я скомпилировал запросы только для тяжелых сценариев), но в скомпилированных запросах я не могу их использовать, и вместо этого мне нужно снова писать регулярный синтаксис запросов. Теперь я делаю те же подзапросы в двух местах, нужно не забывать обновлять оба, если что-то изменится, и так далее. Кошмар.

Этот IQueryable принимает как Expression<Func<T1, T2, T3, ...>>, так и Func<T1, T2, T3, ...>, без каких-либо намеков на снижение производительности во втором случае.

Вот пример кода, который демонстрирует, что я имею в виду:

[TestMethod]
public void QueryComplexityTest()
{
    var users = _dataContext.Users;

    Func<User, bool>                funcSelector =       q => q.UserName.StartsWith("Test");
    Expression<Func<User, bool>>    expressionSelector = q => q.UserName.StartsWith("Test");

    // Returns IEnumerable, and do filtering of data on client-side
    IQueryable<User> func = users.Where(funcSelector).AsQueryable();
    // Returns IQuerible and do filtering of data on server side
    // SELECT ... FROM [dbo].[User] AS [t0] WHERE [t0].[user_name] LIKE @p0
    IQueryable<User> exp = users.Where(expressionSelector);
}

Вы можете объяснить? Я не слежу за ...

Pretzel 29.09.2010 21:11

@Pretzel Я добавил пример кода, демонстрирующий мою проблему.

Valera Kolupaev 30.09.2010 18:13

Спасибо за пример кода! Очень полезно.

Buffalo 12.12.2010 01:56

Транзакции (без использования TransactionScope)

Я думаю, что заблуждение №1 о LINQ to SQL состоит в том, что вам ВСЕГДА НЕОБХОДИМО ЗНАТЬ SQL, чтобы эффективно его использовать.

Еще одна неверно понимаемая вещь о Linq to Sql заключается в том, что вам все равно придется снизить безопасность базы данных до абсурда, чтобы она работала.

Третий момент заключается в том, что использование Linq to Sql вместе с динамическими классами (что означает, что определение класса создается во время выполнения) вызывает огромное количество своевременной компиляции. Что может полностью убить производительность.

Однако очень полезно уже знать SQL. Некоторые SQL-запросы, генерируемые Linq to SQL (и другими ORM), могут быть совершенно сомнительными, и знание SQL помогает диагностировать такие проблемы. Кроме того, Linq to SQL может использовать хранимые процедуры.

Robert Harvey 30.09.2010 18:35

Как LINQ to SQL переводит это!

Предположим, что у нас есть таблица с 3 полями; A, B и C (это целые числа, имя таблицы - "Таблица1").
Показываю так:
[A, B, C]

Теперь мы хотим получить такой результат:
[X = A, Y = B + C]

А у нас есть такой класс:

public class Temp
{
   public Temp(int x, int y)
   {
      this.X = x;
      this.Y = y;
   }

   public int X { get; private set; }
   public int Y { get; private set; }
}

Затем мы используем это так:

using (MyDataContext db = new MyDataContext())
{
   var result = db.Table1.Select(row => 
                   new Temp(row.A, row.B + row.C)).ToList();
}

Сгенерированный SQL-запрос:

SELECT [t0].[A] AS [x], [t0].[B] + [t0].[C] AS [y]
FROM [Table1] AS [t0]

Он переводит .ctor файла Temp. Он знает, что я хочу, чтобы "row.B + row.C" (даже больше ...) включил параметр "y" моего конструктора класса!

Эти переводы меня очень интересуют. Мне это нравится, и я думаю, что писать такие переводчики (LINQ to Something) немного сложно!

Конечно! Плохая новость: LINQ to Entities (4.0) не поддерживает конструкторы с параметрами. (Почему нет?)

Да, мне очень не хватает этой функции в Linq to Entities ...

TDaver 16.02.2011 19:08

Я считаю «Создание дерева выражений» сложной задачей. Есть много вещей, которые меня беспокоят по сравнению с тем, что вы можете сделать с LINQ, LINQ to SQL и ADO.Net в целом.

Объясните, почему Linq не обрабатывает левое внешнее соединение так же просто, как в синтаксисе sql. Смотрите эти статьи: Реализация левого соединения с LINQ, Практическое руководство. Выполнение левых внешних соединений (Руководство по программированию на C#) Я был так разочарован, когда наткнулся на это препятствие, что все мое уважение к языку исчезло, и я решил, что это просто то, что быстро исчезнет. Ни один серьезный человек не захочет работать с синтаксисом, в котором отсутствуют эти проверенные на поле боя примитивы. Если бы вы могли объяснить, почему такого рода операции с наборами не поддерживаются. Я стал бы лучше и более открытым человеком.

интересно. Я пока не нашел необходимости в соединении Left Outer в Linq. Можете ли вы представить ситуации, в которых это будет лучший выбор и как это повлияет на выполнение запроса?

Alexandre Brisebois 07.03.2011 18:00

Левое внешнее соединение не имеет смысла в контексте объектно-реляционного сопоставления (что и делает LINQ). Объекты не должны гидратироваться со всеми их полями, установленными в NULL!

Billy ONeal 07.03.2011 22:06

Но тогда все говорили, что Linq теперь полностью должен заменить SQL. Мне сказали, что только старые упрямые люди используют sql и хранимую процедуру. Я создавал веб-сайт, на котором люди из отдела экономики сопоставляли (сверяли) внешние счета с внутренними учетными записями. Например, мы получили счет на субподрядчика, который работал над проектом. Имя субподрядчика совпадает, активность соответствует расчетам клиента, но код проекта не совпадает. Что-то нужно делать. Угадайте, кто руководитель проекта, свяжитесь с ними, свяжитесь с субподрядчиком и т. д. Итак, это приложение для левого присоединения.

Patrik Lindström 14.04.2011 18:26

Мне нравится, что вы добавили сюда левое присоединение, я не хотел дублировать пост. В противном случае ваш отказ от LINQ будет жестким. Я бы тоже хотел видеть left-join в качестве оператора или что-то в этом роде, но я все время использую LINQ. Бьет к черту старый способ.

Jason Kleban 10.05.2011 23:03

Теперь я более открыт и использую Linq. Я даже стараюсь использовать Linqpad только для повседневных запросов к базе данных. Но теперь меня смущает group by в Linq. (см., например, richardbushnell.net/2008/02/08/…) Это похоже на то, что теперь я понимаю и нет.

Patrik Lindström 16.12.2011 00:14

Мне было трудно найти четкую информацию об анонимных типах, особенно в отношении производительности в веб-приложении. Также я бы предложил лучшие и практичные примеры Lamda-выражений и раздел «Как сделать» в темах, связанных с запросами и производительностью.

Надеюсь, мой краткий список поможет!

Другие вопросы по теме