4. А что вы с ними делаете?
• Поиск = фильтрация
• Превращения = трансформация
/ композиция / декомпозиция
• Сортировка
• Анализ
• Навигация = переход по связям
/ traversing
5. А если нет разницы…
99.9%
всех операций
производимых над данными
повторяются в каждом API
или задаче *
* из личного опыта
6. Вы ещѐ кипятите?
• LINQ призван решить проблему
эффективного взаимодействия
языка программы и источника
данных
• impedance mismatch
9. Бла-бла-бла
• Erik Mejer
• Haskell, Mondrian, X#, Cω, C
#, Visual Basic.
• LINQ, Volta, Rx
• Head of Cloud
Programmibility Team
• LINQ – 2007... ! (.NET 3.5)
• Out of the box – Linq2Objects, Linq2SQL, Linq2XML
10. LINQ
• Универсальный API для
работы с данными
=
Языковые конструкции
+ Набор операторов
+ синтаксический сахар
20. Map
• Взять последовательность
int[]
• Применить функцию к каждому
элементу последовательности
foreach… int.ToString()
• Вернуть набор результатов
return string[]
31. И все, все, все
Select SelectMany Min Max Sum
Count Average Aggregate Cast
ToList Join Reverse GroupBy
Intersect Join Where First Last Any
Except OrderBy Skip Take
SkipWhile FirstOrDefault Single
Union Zip Contains Distinct
Empty Repeat
33. Сахарку ?
Поддерживаются «вложенные» запросы и операторы:
select, where, orderby ascending/descending,
group … by ... into ...
join on … equals …
let
35. LINQ2Anything
• А почему только коллекции?
Нельзя ли все эти Where - ы и лямбды
u => u.Sex = ‘F’
выполнить на другом источнике данных?
• LINQ2Objects =
IEnumerable extensions+ Func ’ s
• LINQ2Anything =
IQueryable extensions + Expressions
36. Те же методы
Select SelectMany Min Max Sum
Count Average Aggregate Cast
ToList Join Reverse GroupBy
Intersect Join Where First Last Any
Except OrderBy Skip Take
SkipWhile FirstOrDefault Single
Union Zip Contains Distinct
Empty Repeat
37. LINQ2Anything
• LINQ2Anything =
IQueryable extenstions + Expressions
• Expressions = код как данные.
Абстрактное синтаксическое дерево
• Задача IQueryable + IQueryProvider –
проанализировать дерево выражений и
преобразовать его в вызовы API
Кто работает с Данными?С какими? Откуда их берёте – БД, XML, вебсервисы, коллекции.Что вы с ними делаете? Какие операции?
Проблема impedance mismatch. Примеры:Объекты плохо ложатся на реляционную структуру. ORMчастично решают проблему несоответствия структур таблиц обьектам, типам данных между БД и ЯП.Xpath для XML – отличный функционал, но не strongly typed.Регулярки для работы с текстом.
Далее будет часто появлятсяобьект Юзер.Просто обьект с простыми св-вами: Имя, Дата рождения(структураdatetime), Пол М или F, Карма – ну какие то баллы.
Пример как выглядит поиск и сортировка на LINQИз коллекции обектов выбираем пользователей рожденных до 1992г и сортируем их по карме. Получаем строго-типизированный обьектUser.Никакой динамики, никаких магических стрингов, запрос проверяется на этапе компиляции, есть интеллисенс.
Появился в Microsoftв 2007 под руководством Erik’a Mejer’a.Он занимался работами над языками….Под его эгидой кроме LINQ ещё были разработаны Volta(аналог GWT) и Rx framework – очень интересная штука для реактивного программирования. Надеюсь расскажу на следующих встречах.Как мы жили до LINQ я себе не представляю.Очень мощный и гибкий инструмент.
LINQ как технология(API) это…Давайте посмотрим каждый ингредиент, чтобы понимать как это вообще возможно.Начнем с Языковых Конструкций
Вывод типа.Плюшка в том, что не надо явно указывать тип переменной. Её тип выведется компилятором. Посмотрите сразу после объявления переменную можно использовать. Строгая типизация сохраняется. Грандиозно экономит время на рефакторинге и когда начинаете писать длиииную строку, не зная ещё что будет в конце.Вару нельзя присвоить nullМожно использовать только для локальных переменных
Анонимный класс можно декларировать и инициализировать налету.Часто бывает для сохранения промежуточных результатов надо быстро состряпать временный объектик из пары полей. Теперь легко.Опять же никакой динамики, строгая типизация, ошибки на этапе компиляции.Область видимости – метод.Можно только св-ва задавать, не методы. Типичный такой DTO внутри метода
Возмем классический статический хелпер. В каждом проекте далеко ни один такой – для формирования дат, работы там со строками и т.д.Вызывают их ИмяКласса.ИмяМетода(параметры). Теперь если я на результате хочу вызвать хелпер, то надо опять все это дело оборачивать вызовом. Много шума.
Товарищи из Микрософта решили по другому. Берем статический метод, помечаем первый параметр ключевым словом this. Теперь могу его использовать от любой стринговой переменной.Мы как бы «расширили» класс стринг, добавили туда метод, не переписывая его.Аналог кажется в руби есть – модули?
Такие методы позволяют писать в continuationстиле.Я сам лично 2 раза имплементировал превращения времени.Очень удобно вместо тогобы чтобы каждый раз писать console.writline сделать расширение котрое можно от любого обьекта вызывать. Можно да, в экстеншен методы передавать параметры.Ну иногда можно и бизнес-логику континуэйшенами оформлять.
Лямбды – анонимные делегаты/методы/функции. В .НЕТе есть такой тип- делегатыЯ могу создать переменную, типа метод/функция.Func – это такие методы которые возвращают значение. не void.isEven – это метод, с 1м параметром int, возвращает bool. И тут же если хочу его определение – это метод с параметром i(смотрите тип параметра указывать не надо, это есть в определении) такой чтоСкобки открываются проверь будет ли остаток от деления и на 2 равняться нолю, и верни результат проверки.Если лямбду можно записать одной строкой, то лишние скобки и ретурны можно опустить.После того как мы сделали лямбду, её можно допустим выполнить.
Action – это для void методов
Функции – это переменные. Их можно допустим передавать как параметры в методы или возвращать.Для примера – я могу сделать метод DoSafely который принимает в себя абсолютно любую функцию, которая в свою очередь имеет 1 параметр юзер и ничего не возвращает – void. И выполняет её отлавливая все ошибки.Теперь я могу по сути все методы, у которых совпадает сигнатура – выполнять безопасно.Реюзабилити кода повышается.Более гибкие решения можно придуматьДелегаты = абстрации на уровне методов. Ну как интерфейс и класс, только у нас делегат и метод.Вопрос к функциональщикам. Угадайте.. Наверное самое часто встречающаяся ф-ция высшего порядка в любом функц. ЯП
Мап.Вот её алгоритм…Давайте попробуем заимплементить её используя знания которые мы теперь имеем.
Параметры:Коллекция Иксов, Ienumerable– интерфейс всех коллекцийФункция, которая берёт Икс и возвращает ИгрекНаш метод возвращает коллекцию ИгрековНазовем её Мап.И дальше пошло тело…
Всё, теперь на любой коллекции можно использовать.Смотрите берем массив интов, вызываем мап.А в качестве функции для трансформации задаем такую лямбду, которая вернет нам новый анонимный тип из пары Number – число и Булеан – четное ли оно.Тепеь мы получем в итоге коллекцию этих анонимных классов. Обратите внимание все строго типизировано опять же.
Мап опытного программиста будет выглядеть так.Поскольку он знает что умные программисты за него уже всё написали.Linq уже содержит в себе метод который называется Select.
Linq 2 Objects – не что иное как набор таких вот расширений поверх Ienumerable.Их там больше 50и штук на все случаи жизни. Давайте посмотрим некоторые примеры
Select – трансформирует данные
Where – фильтр по условию.Условие – лямбда с параметром = обьект и возвращающая тру/фолсПо сути берет лямбду как маску применят ко всем элементам в коллекции и возвращает только те, что удовлетворяют условию.Естественно, поскольку результат where – тоже коллекция, мы опять можем к не применить экстеншен
OrderByOrderByDescendingThenByThenByDescending
Обьединение по признакуЕсть юзеры, года в рождения. Надо найти тех счастливчиков кто родилсяБерем юзеровДжойним их на годаВ качестве «ключа», признака по которому сравнивать выбираем год(лямбдой)В качестве признака годов выбираем сам год,Последний параметр – что делать то с парой из юзера и года если они совпадают… в данном случае нас инетерсует только юзер – возвращаем его.luckyOnes – хотите верте хотите нет – коллекция пользователей.
И таких операторов туевахуча.Вот ту не все, а только те которые с головы помнюИх там больше 50и.
Смотрите сколько шума в запросе – точки, скобки, лямбды… везде переменная UАнтон Кекс вон смотрю исподлобья так на заглавные буквы в методах смотрит..Можно писать и по другому.
Запрос делает абсолютно тоже самое, только убран шум.Добавилось слово from,чтобы как бы задать одну переменную для всех остальных лямбд
Let – позволяет хранить результаты подзапроса в локальной переменной, чтобы не вычислять её каждый раз
Концепт LINQ2Anything – переносим все эти красивые плюшки на другие источники данных, помимо коллекций.
Expressions–такая штука, которая позволяет рассматриватьC# код как структуру данных
Func – это код. Мы его по сути можем только вызвать.
Expression – записывается как лямбда.Но теперь это не исполняемы код, аструктура данных. Посмотрите, можно вытащить параметры, тело… и проанализировать их.Некий аналог reflection’a но с более богатым API
Смотрите с точки зрения пользователя – всё прозрачно. Передаем в метод лямбду. А метод уже если он принимает в себя Func – то будет func. Но если сигнатура метода с Expression параметром – то будет expressionПример – LINQ2SQL.Where – оператор работает уже не с Func а с Expression. Все наши знания можно повторно использовать. API – тот же самый.
Пример как можно разложить дерево выражений.Зная абстрактное синтаксическое дерево и умея его распарсить, можно его перевести в другой язык или вызовы другого API. LINQ2SQL так и делает –парсит выражение и транслирует его в SQL.
НекоторыеLINQ провайдеры к другим источникам данныхLINQ2Amazon – транслирует в вызовы Amazon webserviceAmazon.BookSearch - IQueryable