В чем разница между Entity Framework и Dapper
Что проверяют
Понимаете ли вы, что это инструменты разного уровня: полноценная ORM с отслеживанием изменений против тонкой обёртки над ADO.NET. Следом обычно спрашивают, что вы выберете для конкретного сервиса и можно ли совмещать оба в одном проекте.
Как отвечать
Сравнивайте по тому, что каждый делает за вас:
- Entity Framework Core: модель задаётся классами и
DbContext, запросы пишутся на LINQ и транслируются в SQL. Есть change tracking: вы меняете свойства объекта, аSaveChanges()сам собираетUPDATEв одной транзакции. Плюс миграции, загрузка связей черезInclude, провайдеры под разные СУБД; - Dapper: набор методов расширения для
IDbConnection(Query<T>,QueryAsync<T>,Execute,QueryMultiple). SQL вы пишете сами, Dapper только быстро раскладывает строки результата по свойствам. Ни трекинга, ни миграций, ни генерации запросов.
Про скорость говорите аккуратно. Разрыв был большим во времена EF6, в EF Core он заметно сократился: чтение с AsNoTracking() и проекцией через Select в DTO работает близко к Dapper. Основной оверхед дают отслеживание сущностей и неудачно сгенерированный SQL, а не сам факт ORM. Для массовых операций в EF Core есть ExecuteUpdate и ExecuteDelete, которые не тянут сущности в память.
Практичный ответ: EF Core для доменной логики и записи, где важны транзакции и консистентность, Dapper для тяжёлых отчётов и выборок с ручным SQL. Совмещать можно на одном соединении через context.Database.GetDbConnection().
Где спотыкаются
Говорят «EF медленный» и не могут объяснить почему. Обычно за этим стоят N+1 от ленивой загрузки, трекинг там, где он не нужен, и выборка целых сущностей вместо нужных полей.
Собирают SQL для Dapper конкатенацией строк. Параметры передаются объектом (new { Id = id }), иначе получаете SQL-инъекцию и заодно раздуваете кэш планов в базе.
Забывают, что с Dapper схема, миграции и маппинг связей становятся вашей заботой: для join в несколько объектов нужен multi-mapping со splitOn, и кода становится заметно больше.