Dapper: микро-ORM, мультимаппинг, когда вместо EF
↑ 4.1 ADO.NET, Npgsql и Dapper · ← Предыдущая · → Следующая
Зачем это на собесе
«Dapper или EF Core?» — вопрос на компромиссы. Хороший ответ: разные инструменты, часто вместе.
Объяснение
Dapper — набор extension-методов над IDbConnection: выполняет SQL и мапит результат в объекты. Нет change tracking, LINQ и миграций.
var users = await conn.QueryAsync<User>(
"select id, name from users where created > @since", new { since });
var one = await conn.QuerySingleOrDefaultAsync<User>("select * from users where id = @id", new { id });
await conn.ExecuteAsync("update users set name = @name where id = @id", new { id, name });
// IN со списком
var items = await conn.QueryAsync<Item>("select * from items where id = any(@ids)", new { ids });Multi-mapping
var orders = await conn.QueryAsync<Order, Customer, Order>(
"select o.*, c.* from orders o join customers c on c.id = o.customer_id",
(o, c) => { o.Customer = c; return o; },
splitOn: "id");splitOn указывает, с какой колонки начинается следующий объект.
QueryMultiple
using var grid = await conn.QueryMultipleAsync(sql, args);
var orders = await grid.ReadAsync<Order>();
var total = await grid.ReadSingleAsync<int>();| Критерий | Dapper | EF Core |
|---|---|---|
| Скорость и контроль SQL | максимум | хорошо при правильном использовании |
| Скорость разработки CRUD | ниже | выше |
| Миграции, change tracking | нет | да |
| Сложные отчёты и raw SQL | удобно | возможно |
Типичная схема: EF Core для записи и доменной модели, Dapper для быстрых read-запросов.
Нюансы и подводные камни
snake_caseколонок:DefaultTypeMap.MatchNamesWithUnderscores = true.- Мультимаппинг с неверным
splitOnдаёт пустые объекты. - Не открывайте соединение вручную без
using; Dapper сам откроет закрытое, но не закроет открытое. AddWithValue-подобная типизация: дляGuid,DateOnlyмогут понадобитьсяTypeHandler.- Нет защиты от N+1: проектируйте запросы сами.
Практика
- Реализуйте read-модель списка заказов на Dapper с join-ами.
- Настройте маппинг snake_case.
- Сравните скорость чтения 10 000 строк в EF Core (AsNoTracking) и Dapper.
Вопросы с ответами
Когда Dapper лучше EF?
Для сложных read-запросов, отчётов, критичных по скорости мест и когда нужен полный контроль над SQL.
Можно ли использовать вместе?
Да, при общем соединении/транзакции: EF для записи, Dapper для чтения.
Что такое splitOn?
Название колонки, с которой Dapper начинает мапить следующий тип при мультимаппинге.