Introduction to Dapper — A micro ORM , a simple Object Mapper for .NET
![]()
In general ORM(Object Relational Mapper) is a programming technique used to convert data between two incompatible type systems. It maps database data to objects and creates virtual object database.
.NET ORMs include Entity Frame work, NHibernate and LINQ to SQL. Dapper as a Micro ORM is small ; light weight and has fewer features compared to other ORMs of .NET
Dapper is an open source micro ORM and Nuget library created in 2011 by Sam Saffron, a senior software engineer at Stack Overflow. Initially it was used in production at Stack Overflow and was created to improve performance because at that time LINQ to SQL was too slow in performance. Dapper as a Nuget library will extend your IDbConnection interface with its extensions.
Dapper
Dapper представляет собой инструмент от компании Stack Exchange, который сопоставляет результаты sql-запросов с классами c#. В этом плане Dapper немного похож на Entity Framework. Однако за счет своей легковесности Dapper обеспечивает большую производительность и быстрее позволяет выполнять запросы, чем EF Core. В частности, dapper применяется в работе сайта stackoverflow.com.
Исходные коды dapper, а также ряд дополнительнйо информации по библиотеке можно найти на официальном репозитории на https://github.com/StackExchange/Dapper.
Для работы с Dapper создадим новый проект ASP.NET Core по типу ASP.NET Core Web App (Model-View-Controller). И вначале добавим в него через Nuget пакеты Microsoft.Data.SqlClient и Dapper (при работе с Dapper используется функционал пакета Microsoft.Data.SqlClient):

Затем определим модель User, с которой мы будем работать:
Для работы с Dapper создадим на MS SQL Server небольшую базу данных, которую назовем userstore. Далее в этой базе данных определим одну таблицу, которая соответствует описанию модели User и имеет три поля Id, Name и Age:

Затем также добавим в папку Models интерфейс и класс репозитория, через который будем работать с базой данных:
Для осуществления запросов Dapper предоставляет для объектов IDbConnection метод расширения Query<T> , который в качестве параметра принимает sql-выражение и может возвращать объект типа T, с которым сопоставляются результаты запроса.
Если нужно просто выполнить запрос без необходимости возвращать результат, как в случае с добавлением, обновлением, удалением, то можно использовать метод Execute , в который передается sql-выражение и набор параметров для этого выражения.
Далее изменим файл Startup.cs :
С помощью механизма внедрения зависимостей здесь устанавливается зависимость для интерфейса IUserRepository в виде объекта UserRepository, в конструктор которого передается строка подключения к бд.
В этом случае контроллер HomeController для взаимодействия с бд и выполнения всех базовых CRUD-операций мог бы выглядеть следующим образом:
Dapper: опыт применения

Привет, дорогой читатель, в этой статье я хотел бы поделиться опытом работы с базой данных посредством ORM Dapper на .NET Core, а также рассказать полезные лайфхаки, которые нам помогают удобно использовать его при разработке приложений и рассмотрим как мог бы выглядеть сервис по созданию ведьмаков с использованием Dapper. В данной статье будет много примеров кода и комментариев к нему, а также граблей, по которым мы прошли. Статья рассчитана на тех, кто хочет начать использовать dapper в своих проектах либо тех, кто его уже использует. Итак начнем.
Введение
Dapper — это что-то вроде mini ORM не такая монструозная и более быстрая по сравнению с популярной на .NET Entity Framework. Dapper позволяет писать SQL-запросы к БД и маппить их на C# классы, в общем позволяет связать .Net код и SQL. Из очевидных минусов даппер не автогенерирует код и многие шаблонные запросы, такие как SELECT, INSERT, DELETE, приходится писать вручную, но зато он позволяет писать сложные запросы практически не жертвуя скоростью работы программы и без всякой черной магии и тонны кода.
Как настоящие ведьмаки сразу ринемся в бой с монстрами и посмотрим практические примеры. Будем считать, что БД у нас уже есть и в ней находятся все необходимые таблицы, так что сосредоточимся только на C# составляющей.
Select запрос
Ну и начнем мы, пожалуй, с самых популярных SELECT запросов. В первую очередь нам необходим класс, который мы хотим наполнять данными.
Затем напишем SQL запрос к базе данных, чтобы загрузить все данные по ведьмакам.
Далее выполним данный запрос к БД.
Dapper позволяет связать запрос с классом благодаря алиасам “as” внутри запроса, но требует, чтобы алиас соответствовал названию свойства класса. В нашем примере “witcher_nickname as WitcherNickname” внутри запроса позволяет связать поле “witcher_nickname” из БД со свойством “WitcherNickname” в нашем классе. И все бы хорошо, но что, если мы захотим переименовать свойство класса? Нам придется править все SQL запросы, где используется этот класс, а таких мест может быть много. Чтобы избежать этой проблемы поправим немного наш запрос.
Заменим алиасы на конструкцию nameof(), которая позволит нам связать запрос со свойствами класса, но при этом, в случае рефакторинга класса Witcher в любимой IDE, у нас автоматически подменяется названия свойств в запросах или, в случае удаления свойства, приложение просто не сбилдится, с ошибкой, что в запросе используется имя, которое удалено. В общем, использование данной конструкции значительно уменьшает количество ошибок, головной боли и повышает качество кода.
Запросы с параметрами
Скорее всего, рано или поздно придет аналитик с продактом и скажут, что делать выборку по всем ведьмакам уже неактуально, и надо строить рейтинги по ведьмакам из каждой школы. Мы, конечно, знаем, что Геральт и школа волка даст всем прикурить, но запрос все равно напишем.
В Dapper любой параметр, который необходимо передать в запрос помечается @
Но, как не трудно догадаться, тут можно использовать и обычный класс, давайте создадим класс ведьмачьих школ и передадим его в запрос.
Теперь наш запрос принимает на вход wolfSchool и в SQL подставляется значение свойства Name. В данном примере мы создали экземпляр класса WitcherSchool вручную, но, как можно догадаться, он мог бы быть загружен из базы или еще откуда. Использовать класс вместо анонимного типа полезно, когда у нас есть связанные классы и таблицы, и для написания запроса можно не создавать анонимный класс, а использовать уже готовый.
Ну и соответственно, раз мы теперь передаем в качества параметра не анонимный класс, то мы можем использовать оператор nameof().
Теперь при рефакторинге и изменении класса WolfSchool мы получаем стабильно работающий код и можем не боятся за наши запросы в БД.
Insert запрос
Без лишних отступлений создадим несколько ведьмаков и сохраним их в БД.
Тут мы написали Insert запрос, замапили его на класс ведьмаков, затем создали двух ведьмаков: Геральта и Ламберта и собрали список ведьмаков, которых необходимо добавить в БД. Для выполнения запросов, которые не возвращают результата, используем метод Execute и передаем ему коллекцию ведьмаков для вставки.
Скорее всего, в таблице ведьмаков имеется автоинкрементарное поле id, и было бы неплохо при вставке получить его значения. Перепишем запрос, чтобы получить id добавленных записей.
Ну и соответственно изменим вызов к БД.
Теперь при вставке ведьмаков в БД будут возвращаться id вставленных записей в соответствующем порядке, их можно использовать, например, чтобы потом проставить ссылки на ведьмаков в другие таблицы.
Delete запрос
Предположим, что на школу грифона напала дикая охота и уничтожила всех ведьмаков.
Да, удалять данные в приложениях равно самоубийству, потому что потом придет менеджер и скажет, что хочет сделать корзину или дать возможность пользователю восстанавливать удаленные данные, но иногда есть ситуации, когда и такие запросы пригодятся.
Copy запрос
Часто встречающаяся задача — это копирование данных в таблицах, мы обычно реализуем следующим образом.
В запрос передаем имя ведьмака, чей клон при помощи астральной магии мы хотим создать, и новое название для клона. В БД получаем новую запись с таким же мечом и школой, как у Геральта, но новым именем.
Транзакции
Часто приходится выполнять несколько запросов друг за другом, но в рамках одной транзакции. Например, мы хотим удалить все данные по школе волка и сразу занести в нее двух новых ведьмаков. Вот как это выглядит с использованием Dapper.
Создаем транзакцию методом BeginTransaction(). И во все запросы передаем ее в качестве аргумента функции. В конце не забываем закоммитить транзакцию. Таким образом мы можем выполнить 2 и более запроса за 1 транзакцию. В случае если во время выполнения запроса происходит ошибка, то транзакция автоматически откатывается и вываливается ексепшн.
В заключение
В данной статье отражены основные операции, с которыми сталкиваются наши команды разработки при работе с БД и то, как их можно реализовать при помощи библиотеки Dapper. Сложные SQL запросы пишутся по аналогии. Для получения результатов мапим возвращаемые значения на классы или просто получаем dynamic в ответ, для передачи параметров используем @.
Мы стараемся всегда использовать классы и маппинг на основе конструкции nameof(), чтобы случайный рефакторинг или удаление классов или их свойств не уронили приложение, и все ошибки выявились на этапе билда приложения. Когда лень создавать класс под запрос, то позволяем себе пользоваться анонимными классами, но всегда строго прописываем имя передаваемого параметра, чтобы избежать проблем с рефакторингом.
Для тех, кто заинтересовался в использовании Dapper, ссылка на официальный туториал.
Dapper Discover What is Dapper and Why You Should Use it
Dapper is a micro-ORM created by the team behind Stack Overflow. Dapper is a simple object mapper for .NET and owns the title of King of Micro ORM in terms of speed and is virtually as fast as using a raw ADO.NET data reader. An ORM is an Object Relational Mapper responsible for mapping between a database and a programming language.
- Dapper is a popular open source Object-Relational Mapping (ORM) Library for .NET.
- It makes it easy to work with data in your application by mapping objects to tables in a database.
- Dapper is fast, reliable, and well-tested and has been used in production by some of the world’s largest companies for many years.
- It is very easy to use and has a lot of features that make it a powerful tool for data access.
Is Dapper faster than Entity Framework?
Yes, Dapper is faster than Entity Framework for CRUD operation (querying and saving) due to its simplicity. Unlike EF Core, it doesn’t have to add all complexity, such as tracking values, writing inefficient SQL queries, and supporting features like lazy loading and all inheritance by default.
However, EF Core is relatively very fast as well. The question about which ORM is the best for you should be more about if you want to write most of your SQL query (Dapper) or if you prefer to write LINQ and have EF Core write the SQL query for you.
How does Dapper work?
Dapper provides a simple and concise way to manage your data model without having to write a lot of code. It is also very easy to use, and its code is clean and readable.
Dapper extends the IDbConnection interface by providing helpful extension methods to query your database. It uses dynamic method generation to enable it to inflate POCOs directly from query results. In addition, it allows you to map database columns directly to properties on your POCO.
When using Dapper, all you need is a connection string and a POCO, and then it is a three-step process.
- Create an IDbConnection object.
- Write a query to perform CRUD operations.
- Pass the query as a parameter in any Execute or Query method.
Is Dapper case sensitive or insensitive?
Dapper is case insensitive when mapping column to property. It doesn’t matter if the column name returned is CustomerID or customerid . In both cases, it will be mapped to the right property, such as CustomerId , no matter the casing.
Installation
It is straightforward to install Dapper, you can either download the Dapper NuGet package or clone the Dapper GitHub repository.
To install the Dapper NuGet Package, run the following command in the Package Manager Console:
To clone the Dapper GitHub repository, run the following command in a Git Bash window:
Requirements
Dapper works with any .NET project. This means that it can be used with the following frameworks:
- .NET Core 5.0 and above
- .NET Framework 4.6.1 and above
- .NET Standard 2.0 and above
(Older version is also supported by using older version of Dapper)
Dapper also requires to add a provider package such as:
- Microsoft.Data.SqlClient (for SQL Server)
- System.Data.SqlClient (alternative for SQL Server)
- Microsoft.Data.Sqlite (for SQLite)
- Any other provider package!
Dapper works with any database provider since there is no database-specific implementation.
Once you have installed the required NuGet packages, you can start using Dapper in your project.
Methods
Dapper extension methods can be used to perform various operations in the database, such as fetching data, inserting records, updating records, and deleting records.
Dapper will extend your IDbConnection interface with multiple methods and some of the most commonly used dapper extension methods.
-
: It can execute a command one or multiple times. : It can execute a command and return a reader. : It can execute a command and return a scalar value. : Used to fetch data from the database. : It can execute a query and map the first result. : It can execute a query and map the first result, or a default value if the sequence contains no elements. : It can execute a query and map the first result and throws an exception if there is not exactly one element in the sequence. : It can execute a query and map the first result, or a default value if the sequence is empty; this method throws an exception if there is more than one element in the sequence. : It can execute multiple queries within the same command and map results.
Parameter
Dapper supports many different parameter types. Execute and queries method can use parameters from multiple different ways:
-
: Useful for simple queries where you don’t need to create a separate class to represent your data. : Useful for when you need to create a dynamic list of parameters, or when you need to dynamically change the value of a parameter. : This allows you to specify multiple parameters on an IN clause by using a list. : Useful when working with SQL Server stored procedures that accept varchar input parameters.
Result
When using Dapper, you can map your query results to objects in several ways. The result returned by the queries method can be mapped to multiple types:
-
: Allow you to store the results of a SQL query in an anonymous type. : Allow you to store the results of a SQL query in a strongly typed manner. : Map the result to a strongly typed list with relations. : Execute multiple queries within the same command and map results. : Execute a query and map the result to a list of different types.
Utilities
In addition, to the ability to execute multiple statements in a single round trip to the server, Dapper also provides some additional functionalities that can greatly improve performance in some scenarios.