Какой самый сложный или наиболее непонятый аспект LINQ?[закрыто]
Вопрос
Предыстория:В течение следующего месяца я проведу три лекции о LINQ
в контексте C#
.Я хотел бы знать, каким темам стоит уделить достаточное внимание, исходя из того, что людям может показаться трудным для понимания или о чем у них может сложиться ошибочное впечатление.Я не буду конкретно говорить о LINQ
Для SQL
или Entity Framework, за исключением примеров того, как запросы могут выполняться удаленно с использованием деревьев выражений (и обычно IQueryable
).
Итак, что вам показалось трудным в LINQ
?Что вы видели с точки зрения недопонимания?Примерами может быть любой из следующих, но, пожалуйста, не ограничивайте себя!
- Каким образом
C#
компилятор обрабатывает выражения запроса - Лямбда - выражения
- Деревья выражений
- Методы расширения
- Анонимные типы
IQueryable
- Отложенное или немедленное исполнение
- Потоковое выполнение в сравнении с буферизованным выполнением (например,OrderBy отложен, но буферизован)
- Неявно типизированные локальные переменные
- Считывание сложных типовых сигнатур (например, Перечисляемый.Присоединиться)
Решение
Отложенное выполнение
Другие советы
Я знаю, что концепция отложенного выполнения уже должна быть вбита в меня, но этот пример действительно помог мне понять ее на практике:
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
Что есть нечто большее, чем просто LINQ
к SQL
и функции - это больше, чем просто SQL
парсер, встроенный в язык.
Обозначение большого О.LINQ позволяет невероятно легко писать алгоритмы O(n^4), даже не осознавая этого, если вы не знаете, что делаете.
Я думаю, тот факт, что Lambda
выражение может разрешаться как в дерево выражений, так и в анонимный делегат, поэтому вы можете передавать один и тот же декларативный lambda
выражение обоим IEnumerable<T>
методы расширения и IQueryable<T>
методы расширения.
Взял меня способ слишком долго, чтобы осознать, что многие методы расширения LINQ, такие как Single()
, SingleOrDefault()
и т. д. имеют перегрузки, которые принимают лямбды.
Ты можешь сделать :
Single(x => x.id == id)
и не нужно этого говорить - что я повадился делать из-за какого-то плохого урока
Where(x => x.id == id).Single()
В LINQ to SQL я постоянно вижу, как люди не понимают DataContext, как его можно использовать и как его следует использовать.Слишком многие люди не видят DataContext таким, какой он есть: объектом единицы работы, а не постоянным объектом.
Я много раз видел, как люди пытались выделить DataContext/сеанс и т. д. вместо того, чтобы устанавливать новое время для каждой операции.
А затем происходит удаление DataContext до того, как IQueryable будет оценен, но это больше похоже на то, что люди не понимают IQueryable, чем DataContext.
Другая концепция, с которой я вижу много путаницы, — это синтаксис запроса и синтаксис выражений.Я буду использовать тот вариант, который на данный момент самый простой, часто придерживаясь синтаксиса выражений.Многие люди до сих пор не осознают, что в конце концов они дадут одно и то же, ведь Query в конце концов компилируется в Expression.
Я думаю тот неправильно понятая часть LINQ заключается в том, что это расширение языка, а не расширение или конструкция базы данных.
LINQ
это намного больше, чем LINQ to SQL
.
Теперь, когда большинство из нас использовали LINQ
на коллекциях мы НИКОГДА не вернемся!
LINQ
— это единственная наиболее важная функция .NET со времен Generics в версии 2.0 и анонимных типов в версии 3.0.
И теперь, когда у нас есть Lambda, я с нетерпением жду параллельного программирования!
Я, например, хотел бы знать, нужно ли мне знать, что такое деревья выражений и почему.
Я новичок в LINQ.Вот на что я наткнулся при первой попытке
- Объединение нескольких запросов в один
- Эффективная отладка запросов LINQ в Visual Studio.
Изначально я не осознавал, что синтаксис LINQ не делает требовать IEnumerable<T>
или IQueryable<T>
Чтобы работать, LINQ — это всего лишь сопоставление с образцом.
Вот ответ (нет, я не сделал написать этот блог написал Барт Де Смет, и он один из лучших блоггеров по LINQ, которых я нашел).
У меня все еще есть проблемы с командой «let» (которой я никогда не нашел применения) и SelectMany (которую я использовал, но не уверен, что сделал это правильно)
Понимание случаев утечки абстракции среди провайдеров Linq.Некоторые вещи работают с объектами, но не с SQL (например, .TakeWhile).Некоторые методы можно преобразовать в SQL (ToUpper), а другие — нет.Некоторые методы более эффективны в объектах, тогда как другие более эффективны в SQL (разные методы соединения).
Пара вещей.
- Люди думают о Linq как о Linq to SQL.
- Некоторые люди думают, что они могут начать заменять всю логику foreach запросами Linq, не принимая во внимание влияние этого на производительность.
Хорошо, по требованию я написал кое-что из Expression.Я не на 100% доволен тем, как блоггер и LiveWriter сговорились его отформатировать, но пока сойдет...
В любом случае, вот...Я буду рад любой обратной связи, особенно если есть области, в которых людям нужна дополнительная информация.
Вот, Нравится вам это или нет...
Некоторые сообщения об ошибках, особенно от LINQ to SQL, могут сбивать с толку. ухмылка
Меня, как и всех остальных, пару раз укусила отсрочка казни.Я думаю, что больше всего меня смущает поставщик запросов SQL Server и то, что с ним можно и чего нельзя делать.
Я до сих пор поражен тем фактом, что вы не можете выполнить Sum() для столбца десятичных чисел/денег, который иногда пуст.Использование DefaultIfEmpty() просто не сработает.:(
Я думаю, что в LINQ стоит рассказать о том, как можно столкнуться с проблемами производительности.Например, использовать счетчик LINQ в качестве условия цикла действительно неразумно.
Этот IQueryable принимает оба, Expression<Func<T1, T2, T3, ...>>
и Func<T1, T2, T3, ...>
, не намекая на ухудшение производительности во 2-м случае.
Вот пример кода, который демонстрирует, что я имею в виду:
[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);
}
Я не знаю, можно ли это назвать непонятым, но для меня это просто неизвестно.
Мне было приятно узнать о DataLoadOptions и о том, как я могу контролировать, какие таблицы объединяются при выполнении определенного запроса.
Смотрите здесь для получения дополнительной информации: MSDN:Параметры загрузки данных
Я бы сказал, что наиболее непонятый (или его следует не понимать?) аспект LINQ — это IQueryable и пользовательские поставщики LINQ.
Я уже некоторое время использую LINQ, полностью комфортно себя чувствую в мире IEnumerable и могу решить большинство проблем с помощью LINQ.
Но когда я начал смотреть и читать об IQueryable, Expressions и пользовательских поставщиках linq, у меня закружилась голова.Если вы хотите увидеть довольно сложную логику, посмотрите, как работает LINQ to SQL.
Я с нетерпением жду понимания этого аспекта LINQ...
Как говорили большинство людей, я думаю, что самая непонятая часть заключается в предположении, что LINQ - это просто замена T-SQL.Мой менеджер , который рассматривает он сам, как гуру TSQL, не позволил бы нам использовать LINQ в нашем проекте и даже ненавидит MS за то, что она выпустила такую штуку!!!
Что представляет собой var при выполнении запроса?
Это iQueryable
, iSingleResult
, iMultipleResult
, или оно меняется в зависимости от реализации.Есть некоторые предположения об использовании (как кажется) динамической типизации вместо стандартной статической типизации в C#.
Думаю, не все понимают, насколько легко вложить цикл.
Например:
from outerloopitem in outerloopitems
from innerloopitem in outerloopitem.childitems
select outerloopitem, innerloopitem
group by
до сих пор у меня кружится голова.
Любая путаница в отложенное исполнение должна быть решена путем выполнения простого кода на основе LINQ и игры в окне просмотра.
Скомпилированные запросы
Тот факт, что вы не можете связать IQueryable
потому что это вызовы методов (в то время как все еще не что иное, как возможность перевода SQL!), и то, что это практически невозможно обойти, ошеломляет и приводит к серьезному нарушению DRY.мне нужен мой IQueryable
для специальных запросов, в которых у меня нет скомпилированных запросов (я скомпилировал запросы только для тяжелых сценариев), но в скомпилированных запросах я не могу их использовать, и вместо этого мне нужно снова написать синтаксис обычного запроса.Сейчас я делаю одни и те же подзапросы в 2-х местах, нужно не забыть обновить оба, если что-то изменится и т.д.Кошмар.
Я думаю, что заблуждение №1 относительно LINQ to SQL заключается в том, что вам ВСЕ ЕЩЕ НЕОБХОДИМО ЗНАТЬ SQL, чтобы эффективно его использовать.
Еще одна неправильно понимаемая вещь в Linq to Sql заключается в том, что вам все равно приходится снижать безопасность вашей базы данных до абсурда, чтобы она работала.
Третий момент заключается в том, что использование Linq to Sql вместе с динамическими классами (то есть определение класса создается во время выполнения) приводит к огромному объему компиляции «точно в срок».Что может абсолютно убить производительность.
Ленивая загрузка.
Как уже упоминалось, ленивая загрузка и отложенное выполнение.
Чем LINQ to Objects и LINQ to XML (IEnumerable) отличаются от LINQ to SQL (IQueryable)
КАК построить уровень доступа к данным, бизнес-уровень и уровень представления с помощью LINQ на всех уровнях.... и хороший пример.
Как говорили большинство людей, я думаю, что самая непонятая часть заключается в предположении, что LINQ - это просто замена T-SQL.Мой менеджер, который считает себя гуру TSQL, не позволил бы нам использовать LINQ в нашем проекте и даже ненавидит MS за то, что она выпустила такую штуку!!!
Транзакции (без использования TransactionScope)