Dapper: микро-ORM, мультимаппинг, когда вместо EF

↑ 4.1 ADO.NET, Npgsql и Dapper · ← Предыдущая · → Следующая

Обязательно~3 мин чтенияУровень: middle

Зачем это на собесе

«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>();
КритерийDapperEF 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: проектируйте запросы сами.

Практика

  1. Реализуйте read-модель списка заказов на Dapper с join-ами.
  2. Настройте маппинг snake_case.
  3. Сравните скорость чтения 10 000 строк в EF Core (AsNoTracking) и Dapper.

Вопросы с ответами

Связанные темы