Dapper – micro-ORM — II

Продвинутые возможности

К продвинутым возможностям можем отнести выполнение пакетной вставки данных, получение и разбор нескольких запросов за раз, множественный маппинг.

Пакетная вставка данных как пример использования списка параметров

С помощью Dapper можно осуществлять пакетную вставку данных передав  список данных. Т.е. у нас есть список людей для внесения в базу данных, и с помощью единственной команды можно это провернуть. Лучше сразу на примере показать:

Создаем несколько экземпляров класса Person, и передаем список в качестве параметра в команду Execute. Потом можно визуально проверить результат.

В качестве параметра для пакетной обработки может выступать любая коллекция, которая реализует интерфейс IEnumerable<T>.

Упс!

Ничего же не менялось в коде, и все переменные указаны верно, в чем же дело?

Дело в особенностях реализации Dapper и то, как построен класс Person. На данный момент PersonId является полем, так попробуем его изменить на свойство. Дописываем get, set каждому полю и пробуем снова. Все заработало! Данный момент надо иметь в виду при передаче параметров списком.

Список параметров в запросах

Dapper достаточно интеллектуален и, когда надо, по списку параметров формирует единственный запрос вместо множества.

Пример:

В данном случае необходимо список параметров оборачивать в анонимный класс, так как параметры представлены элементарными типами.

Если посмотреть активность по запросам в профайлере, то можно увидеть, что был единственный запрос:

 

Маппинг сложносоставных методов

Можно научить фреймворк восстанавливать составные типы по сложным запросам в базу данных. Например, нам надо получить всех наших товарищей с заполненными адресами. Для этого не требуется вносить никаких дополнительных данных в исходные классы, все делается на уровне получения данных.

Мы снова воспользуемся Query, однако перегруженным вариантом метода, который принимает несколько шаблонных типов.

В угловых скобках сначала идут типы, на которые надо постараться замапить ответ, последним типом указывается, какие данные будут результирующими. В параметрах метода надо указать текст запроса и правило, по которому надо создавать сложносоставные объекты. Правилом в данном случае выступает лямбда-функция, но как вы понимаете, в общем случае туда можно передавать Func.

Запускаем.

И опять беда. Дело в том, что запрос в текущем виде вернет результат в виде составного набора полей из двух таблиц. Логическое разделение данных идет по первичным ключам, и Dapper исходит из предположения что они названы «Id». Если это не так, то требуется явно указать поле по которому происходит конкатенация таблиц.

Модифицируем код:

 

В метод Query добавили именованный атрибут splitOn с именем поля, по которому идет объединение таблиц.

Мульти запрос

Помимо всего прочего есть возможность сделать запрос из нескольких не связанных между собой таблиц. Может быть удобно, если процедура возвращает несколько наборов данных.

Для обработки таких запросов следует применять метод расширения QueryMultiple, который принимает текст запроса.

Ключевым моментом здесь является то, что надо сразу материализовать запрос:

 

Если не использовать метод ToList(), то при итерации в цикле foreach получите исключение говорящие о том, что возможен единственный проход по списку.

Varchar

Иногда могут быть конфликты в связи с типом параметра, тогда можно задавать их более явно. Например:

 

Больше контроля над параметрами процедуры

Можно явно указывать какие параметры в процедуре будут модифицированы, и что является результатом.

 

Заключение

Рассмотрев Dapper можно сказать, что работая с ним, надо будет вести отдельный класс для запросов, с учетом возможных параметров. Очень интересно посмотреть его использование в реальном проекте, как идет работа с запросами, как они хранятся. Насколько гибко они построены. У меня есть некоторые мысли по этому поводу, но они требуют проверки и более основательного подхода и времени.

Dapper оставляет приятное впечатление, особенно с учетом его скорости работы, что немаловажный фактор.

Несмотря на предостережение построения запросов на лету, хотелось бы все же какой-то функционал по этой теме, чтобы можно было строить запросы в духе LINQ и затем переводить их в текст. При определенной сноровке, мне кажется, можно к этому приспособить Linq2Sql, следует поэкспериментировать в деле построения запросов и передачи параметров в запрос. Параметры в L2S именуются порядковыми номерами.

В таблице сравнения скоростей работы с POCO объектами упоминается PetaPoco, который имеет встроенный составитель запросов. Так что следующий на очереди PetaPoco, думаю, что это не менее интересный и быстрый микро-ORM. После этого уже можно будет выбирать, зная потенциальные возможности и недостатки исходя из конкретных задач и исходных данных.

 

PDF версия

 

Hard’n’heavy!

Оставить комментарий