Предыстория: В течение следующего месяца я проведу три доклада о LINQ или, по крайней мере, о его включении в контекст C#. Я хотел бы знать, каким темам стоит уделить изрядное внимание, исходя из того, что людям может быть трудно понять, или из-за чего у них может сложиться ошибочное впечатление. Я не буду специально говорить о LINQ, SQL или Entity Framework, за исключением примеров того, как запросы могут выполняться удаленно с использованием деревьев выражений (и обычно IQueryable).
Итак, что вы нашли сложным в LINQ? Что вы видели в плане недопонимания? Примеры могут быть любыми из следующих, но, пожалуйста, не ограничивайте себя!
C# обрабатывает выражения запросаIQueryableПервый разговор: Копенгаген, 30 октября. Надеюсь, это будет записано на пленку. (Целый день!) Вторая беседа: Лондон, 19 ноября вечером, Лондонская группа пользователей .NET, вероятно, на Push LINQ. Третий доклад: чтение, 22 ноября, День разработчиков, реализация LINQ to Objects за 60 минут.
круто, я могу посмотреть, смогу ли я провести DDD-день в Ридинге
Голосующие против: пожалуйста, добавьте пояснительный комментарий.
@Jon, извини, но мне нужно закрыть это.
@ Тим: Достаточно честно - он все равно больше не получал ответов. Лично я думаю, что сделал в конечном итоге будет конструктивным, заметьте - мне определенно было полезно увидеть, что люди находят сложным. Я бы, наверное, не стал спрашивать об этом сейчас ...
@Jon - я могу изменить его на «слишком локализованный», если хотите. У меня есть перечисленный список, из которого я выбрал тот, который, на мой взгляд, подходит лучше всего. Я уверен, что этот вопрос будет иметь значение для других, просто он не относится к теме переполнения стека, появившейся почти через три года после того, как вы задали этот вопрос.
@ Тим: Совершенно верно. Возможно, стоит вместо этого перейти на Программисты? Речь идет о программистах как людях ... но также о конкретной технологии, что делает ее сложной. Честно говоря, я не такой уж разборчивый.
@Jon У него довольно много ответов (один принят), ему почти три года, и перенос его на другой сайт был бы не очень конструктивным. Я не совсем уверен, как можно улучшить систему на основе этого опыта. Или, скорее, я не могу сформулировать какие-либо предлагаемые улучшения.
@Tim: Может быть, по поводу меты спросить мнения? Или прямо к Джеффу? Я не знаю, насколько это распространено.
@Jon, это угловые случаи, которые действительно следует рассмотреть, я предлагаю мета. Помните, письмо Джеффа ненавидит. Прикосновение к подобному вопросу вызывает чувство трепета у всех нас [модераторов], поэтому консенсус был бы чрезвычайно полезен.





Ленивая загрузка.
похож на stackoverflow.com/questions/215548/…
Отсроченное исполнение
Право - это явно фаворит среди читателей, что является самым важным в этом вопросе. Я также добавлю в этот микс «буферизация против потоковой передачи», так как это тесно связано - и часто не обсуждается так подробно, как я бы хотел видеть в книгах.
Действительно? Во время изучения Linq мне так много раз указывали на его ленивую природу, что для меня это никогда не было проблемой.
@ALassek, это действительно зависит от того, где вы изучаете LINQ. Я представил для групп пользователей, где никто не знал, чем лениво оценили.
Согласен с ALassek. В документации MSDN четко указано, что LINQ выполняет ленивую оценку. Может быть, настоящая проблема в ленивом программировании разработчиков ... =)
... особенно когда вы понимаете, что он применяется к LINQ к объектам, а не только к LINQ 2 SQL - когда вы видите 10 вызовов веб-методов для получения списка элементов, когда вы уже перечисляете тот же список элементов, и вы подумали, что список уже был оценен
Это должно быть отложенное исполнение, верно? Андерс много раз упоминал об этом в своих видеороликах о LINQ на канале MSDN Channel 9.
@eriawan, отложенные или отложенные работы :)
Знание того, что такое оператор yield и как он работает, IMHO критически важно для полного понимания LINQ.
У меня есть коллеги, которые, даже если мне миллионы раз говорили или после прочтения книги в книге, все равно не получают ленивое поведение LINQ при выполнении.
Кажется, распространено заблуждение, что IEnumerable - это ленивый список, то есть оценивается только один раз.
Что есть больше, чем просто LINQ - SQL, и функции - это больше, чем просто синтаксический анализатор SQL, встроенный в язык.
Мне надоело, что все думают, что: /
Не все делают! Я до сих пор не знаю, что такое LINQ to SQL, и постоянно использую LINQ.
Меня так раздражает, когда я пытаюсь что-то объяснить с помощью LINQ, а другой человек просто смотрит на меня и говорит: «Ооо, я не использую LINQ ни для чего подобного, только SQL» :(
Согласен, многие люди, похоже, не понимают, что LINQ - это инструмент общего назначения.
Я думаю, что тот факт, что выражение Lambda может разрешаться как в дерево выражений, так и в анонимный делегат, поэтому вы можете передать одно и то же декларативное выражение lambda как методам расширения IEnumerable<T>, так и методам расширения IQueryable<T>.
Согласовано. Я ветеран, и я только что понял, что это неявное приведение происходит, когда начал писать свой собственный QueryProvider.
Я думаю, вам следует уделять больше внимания наиболее часто используемым функциям LINQ в деталях - лямбда-выражениям и анонимным типам, а не тратить время на «трудные для понимания» вещи, которые редко используются в реальных программах.
Я согласен с принципом, но на самом деле почти все трудные для понимания биты являются часто используются в реальных программах - просто люди не понимают их.
У меня все еще есть проблемы с командой "let" (которой я никогда не находил применения) и SelectMany (которую я использовал, но не уверен, что сделал это правильно)
Каждый раз, когда вы хотите ввести переменную, вы должны использовать оператор let. Подумайте о традиционном цикле, в котором вы вводите в него переменные и даете каждой переменной имя, чтобы облегчить читаемость кода. Иногда также хорошо, когда у вас есть оператор let, оценивающий результат функции, который вы затем можете выбрать и упорядочить, не оценивая результат дважды.
'let' позволяет создавать составные типы. Удобная штука.
В LINQ to SQL я постоянно вижу людей, не понимающих DataContext, как его можно использовать и как его следует использовать. Слишком много людей не видят DataContext таким, какой он есть - объектом Unit of Work, а не постоянным объектом.
Я видел много раз, когда люди пытались выделить DataContext / session it / etc вместо того, чтобы создавать новое время для каждой операции.
И затем следует избавиться от DataContext до того, как IQueryable будет оценен, но это больше касается людей, не понимающих IQueryable, чем DataContext.
Другая концепция, с которой я вижу много путаницы, - это синтаксис запросов и синтаксис выражений. Я буду использовать самый простой вариант, часто придерживаясь синтаксиса выражений. Многие люди до сих пор не понимают, что в конечном итоге они получат то же самое. В конце концов, Query компилируется в Expression.
Предупреждение: Единицей работы может быть небольшая программа с контекстом данных как синглтоном.
Вы не должны использовать DataContext в синглтоне, это не потокобезопасный.
@Slace, не все программы являются многоголовыми, поэтому можно использовать DataContext в качестве синглтона во многих "настольных" программах.
Меня это укусило (используя DataContext как одноэлемент), когда я делал свой первый проект LINQ to SQL. Я не думаю, что документация и книги делают это достаточно очевидным. На самом деле, я думаю, что название можно было бы улучшить, но я не знаю, как это сделать.
Мне потребовалось несколько раз прочитать статьи ScottY о Linq, чтобы эта мысль пришла мне в голову.
Понимание того, когда происходит утечка абстракции между поставщиками Linq. Некоторые вещи работают с объектами, но не с SQL (например, .TakeWhile). Некоторые методы могут быть переведены в SQL (ToUpper), а другие - нет. Некоторые методы более эффективны в объектах, тогда как другие более эффективны в SQL (различные методы соединения).
Это очень хороший момент. Не помогает то, что Intellisense покажет вам ВСЕ их, и обычно даже компилируется. Тогда вы взорветесь во время выполнения. Я надеюсь, что VS 2010 лучше показывает соответствующие методы расширения.
Я, например, хотел бы знать, нужно ли мне знать, что такое деревья выражений и почему.
Я думаю, что стоит знать, что такое деревья выражений и почему они существуют, но не знать подробностей о том, как их построить самостоятельно. (Их сложно собрать вручную, но компилятор отлично справится с преобразованием лямбда-выражения.)
На самом деле, я думал о том, чтобы сделать несколько записей в блоге о деревьях выражений (поскольку я их «понимаю»). Я считаю очень полезным манипулирование деревьями выражений ...
Однако я не думаю, что они будут полезны для разговоров Джона ;-p
Мне нужно упомянуть их вкратце, но ваши записи в блоге, безусловно, будут приветствоваться :)
Я просто беспокоюсь, что деревья выражений будут похожи на оператор yield: что-то, что оказалось невероятно ценным, несмотря на то, что я сначала не понимал, для чего это было.
Марк Грейвелл. Я хотел бы прочитать ваши записи в блоге по этой теме. С нетерпением жду этого
Я добавил в эту цепочку пост со ссылкой ...
Я новичок в LINQ. Вот то, о чем я споткнулся с первой попытки
Отладка LINQ - это отдельная тема, очень важная. Я думаю, что самая большая слабость LINQ заключается в том, что он позволяет вам писать блоки произвольно сложной логики, которые вы не можете пройти.
это может быть хорошее место для использования LINQ pad
От всей души согласен; вот почему я написал Раскрытие секретов LINQ: связывание и отладка, только что опубликованный на Simple-Talk.com, чтобы вы могли найти помощь.
Да, LinqPad - отличный вторичный инструмент для разработки ваших запросов LINQ. Особенно, если вы только начинаете, и вы новичок в соглашениях / шаблонах.
Хорошо, из-за спроса я написал кое-что из Expression. Я не на 100% доволен тем, как blogger и LiveWriter сговорились отформатировать его, но пока этого достаточно ...
В любом случае, начнем ... Я бы хотел получить обратную связь, особенно если есть области, где людям нужна дополнительная информация.
Вот, нравится это или нет ...
Пара вещей.
Что быстрее, встроенное Linq-to-Sql или Linq-to-Sql с использованием Tsql Sprocs
... и есть ли случаи, когда лучше использовать запросы на стороне сервера (Sproc) или на стороне клиента (встроенный Linq).
Что представляет var при выполнении запроса?
Это iQueryable, iSingleResult, iMultipleResult, или он меняется в зависимости от реализации. Есть некоторые предположения об использовании (что кажется) динамической типизации по сравнению со стандартной статической типизацией в C#.
AFAIK var всегда является конкретным рассматриваемым классом (даже если это анонимный тип), поэтому это никогда IQueryable, ISingleResult или что-либо, начинающееся с «I» (конкретные классы, начинающиеся с «I», не должны применяться).
Понимание синтаксиса «магия». Как синтаксис понимания переводится в вызовы методов и какие вызовы методов выбираются.
Как, например:
from a in b
from c in d
where a > c
select new { a, c }
переводится в вызовы методов.
Я немного рассказал об этом в своем выступлении, но в основном просто «это Сортировать того, что делает компилятор» - включая «он не знает, что перевод вызовет методы расширения и т. д.». Детали, конечно, довольно сложные ...
(Тем не менее, я добавил немного о прозрачных идентификаторах, что имеет отношение к вашему примеру.)
Мне всегда легче понять, если я попытаюсь переосмыслить это как цепочку методов: 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})
group by до сих пор кружит голову.
Любую путаницу в отношении отсроченное исполнение можно разрешить путем пошагового выполнения некоторого простого кода на основе LINQ и игры в окне наблюдения.
Я обнаружил, что реализация небольшого количества LINQ to Objects для развлечения действительно помогает :) Но да, это немного сбивает с толку - конечно, если я какое-то время не использовал LINQ, мне нужно вернуться к подписям. Точно так же «присоединиться» к «присоединиться к» часто заставляет меня ...
Для LINQ2SQL: ознакомьтесь с некоторыми из сгенерированных SQL и напишите запросы LINQ, которые преобразуются в хороший (быстрый) SQL. Это часть более серьезной проблемы, связанной с пониманием того, как сбалансировать декларативный характер запросов LINQ с реализмом, необходимым для быстрого их выполнения в известной среде (SQL Server).
Вы можете получить совершенно другой сгенерированный SQL-запрос, изменив крошечный элемент в коде LINQ. Это может быть особенно опасно, если вы создаете дерево выражений на основе условных операторов (т.е. добавляете дополнительные критерии фильтрации).
Первоначально я не осознавал, что синтаксис LINQ не требует для работы IEnumerable<T> или IQueryable<T>, а LINQ - это всего лишь сопоставление с образцом.
Вот ответ (нет, я, не сделал, пишу этот блог, это сделал Барт Де Смет, и он один из лучших блоггеров по LINQ, которых я нашел).
Вы также можете найти этот пост в блоге интересным: msmvps.com/blogs/jon_skeet/archive/2008/02/29/…
Хороший пост, Джон (я подписался на твой блог, правда, совсем недавно).
Меня немного разочаровывает то, что синтаксис выражения запроса поддерживает только подмножество функций LINQ, поэтому вы не можете время от времени связывать методы расширения в цепочку. Например. метод Distinct нельзя вызвать с использованием синтаксиса выражения запроса. Чтобы использовать метод Distinct, вам необходимо вызвать метод расширения. С другой стороны, синтаксис выражения запроса во многих случаях очень удобен, так что вы тоже не хотите его пропускать.
В доклад о LINQ можно было бы включить некоторые практические рекомендации о том, когда предпочесть один синтаксис другому и как их смешивать.
Лично я рад, что синтаксис выражения запроса не включает очень много операторов. Точечная нотация хороша, когда вам нужно ее использовать, и этот баланс сохраняет C# по-прежнему малым языком разумно. Часть спецификации, содержащая выражение запроса, приятная и короткая - мне бы не хотелось иметь действительно длинный раздел.
Как уже упоминалось, отложенная загрузка и отложенное выполнение
Чем LINQ to Objects и LINQ to XML (IEnumerable) отличаются от LINQ to SQL (IQueryable)
КАК для создания уровня доступа к данным, бизнес-уровня и уровня представления с LINQ на всех уровнях ... и хороший пример.
Первые два я могу сделать. Я бы не хотел пробовать третий вариант в смысле «это правильный способ» ...
+1, пока вы не указали на это, я не осознавал, что LINQ-to-Objects и LINQ-to-XML были IEnumerable в отличие от LINQ-to-SQL как IQueryable, но это имеет смысл. Спасибо!
Я не знаю, можно ли это считать неправильно понятым, но для меня это просто неизвестно.
Мне было приятно узнать о 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 минут»
Как говорило большинство людей, я думаю, что наиболее неправильно понимаемая часть - это предположение, что LINQ - это просто замена T-SQL. Мой менеджер, который сам был считает как гуру TSQL, не позволил нам использовать LINQ в нашем проекте и даже ненавидит MS за выпуск такой штуки !!!
Слишком много людей используют его как замену TSQL. Большинство из них никогда не слышали о плане исполнения.
+1, потому что я согласен с вашим менеджером, по крайней мере, в том, что касается разрешения LINQ to SQL в любом проекте. LINQ to Objects - совсем другое дело.
Я думаю, что часть LINQ неправильно понятая в заключается в том, что это расширение языка, а не расширение или конструкция базы данных.
LINQ - это намного больше, чем LINQ to SQL.
Теперь, когда большинство из нас использовали LINQ в коллекциях, мы НИКОГДА не вернемся!
LINQ - единственная наиболее важная функция .NET со времен Generics в версии 2.0 и анонимных типов в версии 3.0.
А теперь, когда у нас есть Lambda, я не могу дождаться параллельного программирования!
Я бы даже назвал это более значимым, чем анонимные типы, и, возможно, даже больше, чем дженерики.
Я знаю, что концепция отложенного выполнения должна быть уже внедрена в меня, но этот пример действительно помог мне понять ее на практике:
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
Обозначение Big O. LINQ позволяет невероятно легко писать алгоритмы O (n ^ 4), даже не осознавая этого, если вы не знаете, что делаете.
Как насчет примера?
Что касается примера, возможно, он имеет в виду тот факт, что предложение Select очень легко содержать много операторов Sum (), каждый из которых вызывает еще один проход по всему набору записей.
На самом деле, возможно, даже стоит рассмотреть, что такое большая нотация O и почему она важна, а также несколько примеров неэффективных результирующих запросов. Я думаю, это то, что предлагал оригинальный плакат, но я подумал, что все равно упомяну об этом. - Обновлено: только что понял, что этому посту 1,5 года :-)
Это не было бы O (n ^ x), это было бы O (xn), то есть просто O (n).
Попытка выполнить соединение без оператора соединения приведет к 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}. И я действительно видел это написанным раньше. Работает, но очень медленно.
Некоторые сообщения об ошибках, особенно от LINQ to SQL, могут сбивать с толку. ухмылка
Меня, как и всех, пару раз укусила отложенная казнь. Я думаю, что больше всего меня сбивает с толку поставщик запросов SQL Server и то, что вы можете и не можете с ним делать.
Я все еще поражен тем фактом, что вы не можете выполнить Sum () для столбца десятичных чисел / денег, который иногда бывает пуст. Использование DefaultIfEmpty () просто не сработает. :(
Должно быть довольно легко указать где в этом запросе, чтобы сумма работала
Я уверен, что почти один знает: вы можете использовать встроенные if в запросе linq. Что-то вроде этого:
var result = from foo in bars where (
((foo.baz != null) ? foo.baz : false) &&
foo.blah == "this")
select foo;
Я полагаю, вы также можете вставлять лямбды, хотя я не пробовал.
Это просто условное выражение - почему не стал бы вы можете его использовать?
У меня сложилось (вероятно, ошибочное) впечатление, что это похоже на обычное «если»: вы бы не увидели вложения таких обычных «если», не так ли? или я мог ошибаться ...
Если - это инструкция, а условный оператор - это выражение. Это разные формы одной и той же концепции ветвления. В этом случае, однако, вы можете сделать "foo.baz ?? false" и использовать нулевой оператор объединения :-)
Я думаю, что больше людей знают тернарный оператор, чем противоположный ..
Условные выражения, приводящие к логическим значениям, могут быть сокращены до логических и / или выражений, поэтому (foo.baz != null) ? foo.baz : false эквивалентен (foo.baz != null) && foo.baz. Я думаю, что это можно применить к любому троичному выражению, которое может быть передано как условие where. Так что неудивительно, ИМХО
Тот факт, что вы не можете связать IQueryable, потому что они являются вызовами методов (в то время как по-прежнему не что иное, как переводимый SQL!) И что это практически невозможно обойти, это ошеломляет и создает огромное нарушение DRY. Мне нужны мои IQueryable для ad-hoc, в которых у меня нет скомпилированных запросов (я скомпилировал запросы только для тяжелых сценариев), но в скомпилированных запросах я не могу их использовать, и вместо этого мне нужно снова писать обычный синтаксис запросов. Теперь я делаю те же подзапросы в двух местах, нужно не забывать обновлять оба, если что-то изменится, и так далее. Кошмар.
Мне потребовалось слишком много времени для путь, чтобы понять, что многие методы расширения LINQ, такие как Single(), SingleOrDefault() и т. д., Имеют перегрузки, которые принимают лямбды.
Ты можешь сделать :
Single(x => x.id == id)
и не нужно этого говорить - что из-за плохого учебника я привык делать
Where(x => x.id == id).Single()
+1, очень красиво. Буду иметь в виду.
Я тоже все время забываю об этом. Это также верно и для Count(), среди прочих. Знаете ли вы, есть ли разница в производительности помимо очевидного бонуса читаемости кода?
В университете мой преподаватель хотел снять баллы за использование этих перегрузок !! Я доказал, что он неправ!
Это может показаться странным, но я предпочитаю второй синтаксис. Я считаю это более читаемым.
Я не думаю, что все понимают, насколько легко вложить петлю.
Например:
from outerloopitem in outerloopitems
from innerloopitem in outerloopitem.childitems
select outerloopitem, innerloopitem
+1, эй. это довольно мощно.
Как говорило большинство людей, я думаю, что наиболее неправильно понимаемая часть - это предположение, что 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 Я добавил пример кода, демонстрирующий мою проблему.
Спасибо за пример кода! Очень полезно.
Транзакции (без использования TransactionScope)
Я думаю, что заблуждение №1 о LINQ to SQL состоит в том, что вам ВСЕГДА НЕОБХОДИМО ЗНАТЬ SQL, чтобы эффективно его использовать.
Еще одна неверно понимаемая вещь о Linq to Sql заключается в том, что вам все равно придется снизить безопасность базы данных до абсурда, чтобы она работала.
Третий момент заключается в том, что использование Linq to Sql вместе с динамическими классами (что означает, что определение класса создается во время выполнения) вызывает огромное количество своевременной компиляции. Что может полностью убить производительность.
Однако очень полезно уже знать SQL. Некоторые SQL-запросы, генерируемые Linq to SQL (и другими ORM), могут быть совершенно сомнительными, и знание SQL помогает диагностировать такие проблемы. Кроме того, 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 ...
Я считаю «Создание дерева выражений» сложной задачей. Есть много вещей, которые меня беспокоят по сравнению с тем, что вы можете сделать с LINQ, LINQ to SQL и ADO.Net в целом.
Объясните, почему Linq не обрабатывает левое внешнее соединение так же просто, как в синтаксисе sql. Смотрите эти статьи: Реализация левого соединения с LINQ, Практическое руководство. Выполнение левых внешних соединений (Руководство по программированию на C#) Я был так разочарован, когда наткнулся на это препятствие, что все мое уважение к языку исчезло, и я решил, что это просто то, что быстро исчезнет. Ни один серьезный человек не захочет работать с синтаксисом, в котором отсутствуют эти проверенные на поле боя примитивы. Если бы вы могли объяснить, почему такого рода операции с наборами не поддерживаются. Я стал бы лучше и более открытым человеком.
интересно. Я пока не нашел необходимости в соединении Left Outer в Linq. Можете ли вы представить ситуации, в которых это будет лучший выбор и как это повлияет на выполнение запроса?
Левое внешнее соединение не имеет смысла в контексте объектно-реляционного сопоставления (что и делает LINQ). Объекты не должны гидратироваться со всеми их полями, установленными в NULL!
Но тогда все говорили, что Linq теперь полностью должен заменить SQL. Мне сказали, что только старые упрямые люди используют sql и хранимую процедуру. Я создавал веб-сайт, на котором люди из отдела экономики сопоставляли (сверяли) внешние счета с внутренними учетными записями. Например, мы получили счет на субподрядчика, который работал над проектом. Имя субподрядчика совпадает, активность соответствует расчетам клиента, но код проекта не совпадает. Что-то нужно делать. Угадайте, кто руководитель проекта, свяжитесь с ними, свяжитесь с субподрядчиком и т. д. Итак, это приложение для левого присоединения.
Мне нравится, что вы добавили сюда левое присоединение, я не хотел дублировать пост. В противном случае ваш отказ от LINQ будет жестким. Я бы тоже хотел видеть left-join в качестве оператора или что-то в этом роде, но я все время использую LINQ. Бьет к черту старый способ.
Теперь я более открыт и использую Linq. Я даже стараюсь использовать Linqpad только для повседневных запросов к базе данных. Но теперь меня смущает group by в Linq. (см., например, richardbushnell.net/2008/02/08/…) Это похоже на то, что теперь я понимаю и нет.
Мне было трудно найти четкую информацию об анонимных типах, особенно в отношении производительности в веб-приложении. Также я бы предложил лучшие и практичные примеры Lamda-выражений и раздел «Как сделать» в темах, связанных с запросами и производительностью.
Надеюсь, мой краткий список поможет!
Мне было бы интересно узнать, когда вы собираетесь провести эти переговоры, и есть ли способ просмотреть их в Интернете.