Ответ 1
Отложенное выполнение
Справочная информация. В течение следующего месяца я расскажу три слова или, по крайней мере, включив LINQ
в контексте C#
. Я хотел бы знать, какие темы стоит уделять достаточное внимание, исходя из того, что люди могут найти трудно понять или что они могут иметь ошибочное впечатление. Я не буду говорить конкретно о LINQ
- SQL
или Entity Framework, кроме как примеры того, как запросы могут выполняться удаленно с помощью деревьев выражений (и обычно IQueryable
).
Итак, что вы нашли трудно о LINQ
? Что вы видели с точки зрения недоразумений? Примерами могут быть любые из следующих, но, пожалуйста, не ограничивайте себя!
C#
обрабатывает выражения запросаIQueryable
Отложенное выполнение
Я знаю, что к настоящему времени мне следует избить концепцию отложенного исполнения, но этот пример действительно помог мне получить практическое представление об этом:
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
, встроенный в язык.
Знак Big O. LINQ позволяет невероятно легко писать O (n ^ 4) алгоритмы, не осознавая этого, если вы не знаете, что делаете.
Я думаю, что выражение Lambda
может разрешить как дерево выражений, так и анонимный делегат, поэтому вы можете передать одно и то же декларативное выражение Lambda
как методам расширения IEnumerable<T>
, так и методам расширения IQueryable<T>
.
Взял меня способ слишком долго, чтобы понять, что многие методы расширения LINQ, такие как Single()
, SingleOrDefault()
и т.д., имеют перегрузки, которые берут lambdas.
Вы можете сделать:
Single(x => x.id == id)
и не нужно говорить об этом - какой-то плохой учебник заставил меня привыкнуть делать
Where(x => x.id == id).Single()
В LINQ to SQL я постоянно вижу людей, которые не понимают DataContext, как его можно использовать и как его использовать. Слишком много людей не видят DataContext для того, что это такое, объект Unit of Work, а не постоянный объект.
Я видел много раз, когда люди пытаются изолировать DataContext/session it/etc, а не делать новое время для каждой операции.
И затем, используя DataContext, перед тем, как IQueryable был оценен, но это больше, потому что люди не понимают IQueryable, чем DataContext.
Другая концепция, с которой я вижу много путаницы, - это синтаксис запроса и синтаксис выражения. Я буду использовать то, что когда-либо было самым простым в этот момент, часто придерживаясь синтаксиса выражения. Многие люди до сих пор не понимают, что в конечном итоге они получат одно и то же, Query скомпилирован в Expression.
Я думаю, что некорректная часть LINQ заключается в том, что это расширение языка, а не расширение или конструкция базы данных.
LINQ
намного больше, чем LINQ to SQL
.
Теперь, когда большинство из нас использовали LINQ
в коллекциях, мы НИКОГДА не вернемся!
LINQ
- единственная наиболее значимая функция .NET с использованием Generics в версии 2.0 и анонимных типов в версии 3.0.
И теперь, когда у нас есть Лямбда, я не могу дождаться параллельного программирования!
Мне бы хотелось знать, нужно ли мне знать, какие деревья выражений и почему.
Я новичок в LINQ. Здесь вещи, которые я наткнулся в своей первой попытке
Что-то, чего я изначально не понял, было то, что синтаксис LINQ не требует работы IEnumerable<T>
или IQueryable<T>
, LINQ - это просто соответствие шаблонов.
alt text http://bartdesmet.info/images_wlw/QIsIQueryabletheRightChoiceforMe_13478/image_thumb_3.png
Вот ответ (нет, я не писал этот блог, Барт Де Смет сделал, и он один из лучших блоггеры по LINQ, которые я нашел).
У меня все еще есть проблема с командой "let" (которую я никогда не использовал для) и SelectMany (которую я использовал, но я не уверен, что я сделал это правильно)
Понимание того, когда абстракция у провайдеров Linq протекает. Некоторые вещи работают на объектах, но не на SQL (например,.TakeWhile). Некоторые методы могут быть переведены в SQL (ToUpper), а другие - нет. Некоторые методы более эффективны в объектах, где другие более эффективны в SQL (разные методы соединения).
Пара вещей.
ОК, из-за спроса, я написал некоторые из материалов Expression. Я не на 100% доволен тем, как блоггер и LiveWriter сговорились отформатировать его, но теперь это будет сделано...
В любом случае, здесь идет... Мне понравилась бы любая обратная связь, особенно если есть области, где люди хотят получить больше информации.
Вот он, нравится или ненавидит его...
Некоторые сообщения об ошибках, особенно из LINQ to SQL, могут быть довольно запутанными. Гринь
Я был укушен отложенным исполнением пару раз, как и все остальные. Я считаю, что для меня самая запутанная вещь - поставщик запросов SQL Server, и что вы можете и не можете с ней сделать.
Я все еще удивляюсь тому, что вы не можете сделать Sum() в столбце десятичной/денежной единицы, который иногда пуст. Использование DefaultIfEmpty() просто не сработает.: (
Я думаю, что отличная вещь, чтобы покрыть в LINQ, - это то, как вы можете справиться с трудностями. Например, использование LINQ count в качестве условия цикла действительно, действительно не умное.
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);
}
Я не знаю, соответствует ли это неправильному пониманию, но для меня просто неизвестно.
Мне было приятно узнать о DataLoadOptions и как я могу контролировать, какие таблицы объединяются, когда я делаю конкретный запрос.
См. здесь для получения дополнительной информации: MSDN: DataLoadOptions
Я бы сказал, что самый непонятый (или должен быть непонятным?) аспект LINQ IQueryable и пользовательских поставщиков LINQ.
Я уже некоторое время использую LINQ и вполне комфортно в мире IEnumerable и могу решить большинство проблем с LINQ.
Но когда я начал смотреть и читать о IQueryable, а также выражениях и пользовательских провайдерах linq, это заставило мою голову вращаться. Посмотрите, как работает LINQ to SQL, если вы хотите увидеть довольно сложную логику.
Я с нетерпением жду понимания этого аспекта LINQ...
Как и большинство людей, я думаю, что самая непонятная часть предполагает, что LINQ - это просто замена T-SQL. Мой менеджер, который считает себя гуру TSQL, не позволит нам использовать LINQ в нашем проекте и даже ненавидит MS за то, что выпустил такую вещь!!!
Что представляет var при выполнении запроса?
Это iQueryable
, iSingleResult
, iMultipleResult
, или он изменяется в зависимости от реализации. Есть некоторые предположения о том, как использовать (то, что кажется) динамическое типирование и стандартное статическое типирование на С#.
Как легко вложить петлю, я не думаю, что все понимают.
Например:
from outerloopitem in outerloopitems
from innerloopitem in outerloopitem.childitems
select outerloopitem, innerloopitem
group by
все еще заставляет мою голову вращаться.
Любая путаница в отношении отложенного исполнения должна быть разрешена путем перехода через некоторый простой код на основе LINQ и игры в окне просмотра.
Тот факт, что вы не можете связать IQueryable
, потому что это вызовы методов (хотя все еще ничего, кроме SQL-переводимого!), и что почти невозможно обойтись, это разумно и создает огромное нарушение DRY. Мне нужен мой IQueryable
для ad-hoc, в котором у меня нет скомпилированных запросов (у меня только скомпилированные запросы для тяжелых сценариев), но в скомпилированных запросах я не могу их использовать и вместо этого нужно снова писать регулярный синтаксис запроса, Теперь я делаю одни и те же подзапросы в 2-х местах, не забудьте обновить их, если что-то изменится, и так далее. Кошмар.
Я думаю, что неправильное представление №1 о LINQ to SQL заключается в том, что вы ВСЕГДА ЗНАТЬ SQL, чтобы эффективно использовать его.
Еще одна непонятная вещь о Linq to Sql заключается в том, что вам все равно нужно снизить безопасность базы данных до абсурда, чтобы заставить ее работать.
Третья точка заключается в том, что использование Linq to Sql вместе с динамическими классами (что означает, что определение класса создается во время выполнения) вызывает огромное количество компиляции точно в момент времени. Что может абсолютно убить производительность.
Lazy Loading.
Как уже упоминалось, ленивая загрузка и отсроченное выполнение
Как LINQ для объектов и LINQ to XML (IEnumerable) отличаются от LINQ to SQL (IQueryable)
КАК создать уровень доступа к данным, бизнес-уровень и уровень представления с LINQ во всех слоях... и хороший пример.
Как и большинство людей, я думаю, что самая непонятная часть предполагает, что LINQ - это просто замена T-SQL. Мой менеджер, который считает себя гуру TSQL, не позволит нам использовать LINQ в нашем проекте и даже ненавидит MS за то, что выпустил такую вещь!!!
Транзакции (без использования TransactionScope)