Миф #1
Все LINQ запросы должны начинаться с ключевого слова 'var'. По сути основная цель ключевого слова 'var' — начать LINQ запрос!
Ключевое слово var и LINQ — это самостоятельные концепции. Ключевое слово var позволяет компилятору вывести тип локальной переменной на основании начального присваивания (неявная типизация). К примеру, следующий код:
точный эквивалент для:
потому что компилятор выводит тип переменной s как string.
Аналогично, следующий запрос:
точный эквивалент для:
Можно заметить, всё чего мы добились с помощью ключевого слова var — это создали сокращение для IEnumerable<string>. Многие люди любят такую запись, поскольку она короче; другие же считают, что неявная типизация способна сделать код менее понятным.
Бывают ситуации, в которых для LINQ запросов необходимо ключевое слово var. Это происходит при проекции в анонимный тип:
Следующий пример показывает, как использовать анонимный тип вне LINQ контекста:
Миф #2
Все LINQ запросы должны использовать синтаксис запросов.
Существует два способа записи LINQ запросов: лямбда синтаксис и синтаксис запросов.
Пример лямбда синтаксиса:
Пример, аналогичный предыдущему но использующий синтаксис запросов:
Логически, компилятор транслирует синтаксис запросов в лямбда синтаксис. Это означает, что всё, что может быть выражено с помощью синтаксиса запросов, так же может быть выражено в лямбда синтаксисе. Синтаксис запросов может быть намного проще с запросами включающими более одной переменной диапазона. (В данном примере, мы использовали только одну переменную диапазона p, так что оба запроса выглядят одинаково просто).
Не все операторы доступны в синтаксисе запросов, так что эти два вида синтаксиса скорее дополняют друг друга. Чтобы получить лучшее от каждого, вы можете смешивать стили запросов в одном выражении (см. миф # 5).
Миф #3
Чтобы извлечь всех клиентов из таблицы, вы должны использовать запрос на подобии этого: var query = from c in db.Customers select c.
Выражение
является слишком многословным! Вы можете просто использовать:
Аналогично, следующий LINQ to XML запрос:
может быть упрощен до:
И этот запрос:
можно упростить до:
Миф #4
Чтобы воспроизвести SQL запрос в LINQ, вы должны сделать LINQ запрос максимально похожим на SQL запрос.
LINQ и SQL — разные языки, использующие разные концепции.
Возможно, главным барьером продуктивного использования LINQ является синдром «думать в терминах SQL»: мысленно представлять запрос на языке SQL, а затем переводить его на LINQ. Результатом будет постоянная борьба с API!
Однажды начав думать исключительно в терминах LINQ, ваши запросы будут иметь очень мало общего с их SQL-аналогами. Во многих случаях, они будут также значительно проще.
Миф #5
Для эффективного соединения в LINQ, вы должны использовать ключевое слово join.
Это правда, но только для запросов к локальным коллекциям. Когда вы создаете запрос к базе данных, ключевое слово join вовсе необязательно: операция соединения может быть заменена использованием нескольких from-ов и подзапросов. Несколько from-ов и подзапросы являются более универсальными: вы так же можете реализовать соединение не по равенству (non-equi-join).
Более того в LINQ to SQL и Entity Framework вы можете запрашивать свойства ассоциации, уменьшающие потребность в join-ах! К примеру, следующий код показывает, как можно извлечь имена и идентификаторы всех клиентов, не совершивших ни одной покупки:
Или извлечь клиентов, не совершивших покупку на сумму свыше $1000:
Заметьте, мы смешали лямбда синтаксис и синтаксис запросов. Большее количество примеров свойств ассоциаций, руководства по соединениям и смешанного синтаксиса смотри на LINQPad.
Миф #6
Поскольку результатом SQL запроса является плоский набор данных, то LINQ запросы должны создаваться так, чтобы возвращать также плоский набор данных.
Это следствие из Мифа #4. Одно из основных преимуществ LINQ заключается в том, что вы можете:
- Запрашивать структурированный объект через свойства ассоциации (вместо того чтобы соединяться вручную);
- Проецировать прямо в иерархию объектов.
В принципе, 1 и 2 независимы, однако 1 помогает 2. К примеру, если вы хотите извлечь номера клиентов в штате WA вместе с их покупками, вы можете использовать следующий код:
Иерархический результат этого запроса намного проще в работе, чем плоский набор данных.
Мы можем достигнуть такого же результата, не используя свойства ассоциаций:
Миф #7
Чтобы реализовать внешнее соединение в LINQ to SQL вы всегда должны использовать оператор DefaultIfEmpty().
Это правда, если вам нужен плоский набор данных. Пример в предыдущем мифе, транслируется в левое внешнее соединение (left outer join) в SQL и не требует оператора DefaultIfEmpty.
Миф #8
Запросы LINQ to SQL или Entity Framework будут выполняться как единое целое, только если они были построены в один шаг.
LINQ использует отложенную модель выполнения, то есть запросы выполняются не во время создания, а во время перечисления. Это означает, вы можете конструировать ваши запросы во столько шагов, во сколько захотите, и они не попадут на сервер до тех пор, пока вы не начнёте использовать результат.
К примеру, следующий запрос извлекает имена всех клиентов совершивших две покупки, чьё имя начинается с символа 'А'. Мы построили этот запрос в три шага:
Миф #9
Метод не может вернуть запрос, если он заканчивается оператором 'new'.
Трюк заключается в проекции в обычный именованный тип, используя инициализатор объектов:
Класс NameDetails определен следующим образом:
Миф #10
Лучший способ использования LINQ to SQL- это инстанциировать единственный экземпляр класса DataContext в статическом свойстве и использовать этот общий экземпляр на протяжении всей жизни приложения.
Такая стратегия приведет к устаревшим данным, поскольку объекты отслеживаемые экземпляром DataContext не обновляются при повторном запросе.
Используя единственный экземпляр класса DataContext вы получите много неприятностей, поскольку он не является потокобезопастным.
Правильной стратегией является создание нового экземпляра DataContext по каждому запросу объектов, делая его жизнь довольно короткой. То же самое касается Entity Framework.
Ссылка на оригинал: http://www.albahari.com/nutshell/10linqmyths.aspx
Комментариев нет:
Отправить комментарий