Dapper vs Entity Framework Core: Which Should You Use in .NET?

Dapper and Entity Framework Core are the two most popular ways to talk to SQL Server from .NET. Debates about them often turn into speed contests, but the better question is: how much do you want to write SQL yourself, and how much do you want the framework to do for you?

Dapper vs Entity Framework Core comparison

Dapper in one minute

Dapper is a "micro-ORM": a small library of extension methods on IDbConnection. You write the SQL; Dapper runs it and maps the results to your objects.

using var conn = new SqlConnection(connectionString);

var employees = await conn.QueryAsync<Employee>(
    @"SELECT EmployeeId, FullName, DepartmentId
      FROM dbo.Employee
      WHERE DepartmentId = @DeptId AND IsActive = 1",
    new { DeptId = deptId });

Parameters are passed as an anonymous object, so queries stay safe from SQL injection.

EF Core in one minute

EF Core is a full ORM. You describe your model in C#, write LINQ, and EF Core generates the SQL, tracks changes and saves them, with migrations to evolve the schema.

var employees = await db.Employees
    .Where(e => e.DepartmentId == deptId && e.IsActive)
    .Select(e => new { e.EmployeeId, e.FullName, e.DepartmentId })
    .ToListAsync();

Side-by-side

DapperEF Core
Who writes the SQLYouEF Core (from LINQ)
Raw overheadVery lowLow to moderate; close to Dapper for well-written, no-tracking queries
Change trackingNoYes
Relationships and loadingManual (multi-mapping)Built in (Include, navigation properties)
Schema migrationsSeparate toolBuilt in
Learning curveSmall, if you know SQLLarger: tracking, loading strategies, generated SQL
Complex SQL (CTEs, window functions, hints)Easy: it is just SQLPossible via raw SQL, less natural

Choose Dapper when

  • Your team is strong in SQL and wants full control of every query.
  • The work is read-heavy: reports, dashboards, search screens, APIs returning projections.
  • You work mostly with stored procedures or an existing database you do not own.
  • You need hand-tuned queries with hints, CTEs or window functions.

Choose EF Core when

  • You build a domain-rich application with lots of create, update and delete logic.
  • You want migrations, relationships and change tracking out of the box.
  • Developer productivity and maintainability matter more than squeezing every microsecond.
  • You are happy to learn its performance habits: no-tracking reads, projections and checking generated SQL.

The pragmatic answer: use both

Many production systems use EF Core for everyday CRUD and business logic, and Dapper (or EF Core's raw SQL methods) for a handful of heavy reports and performance-critical queries. They can share the same connection string, and even the same connection:

var conn = db.Database.GetDbConnection();   // EF Core's connection
var rows = await conn.QueryAsync<PayrollSummary>(sql, new { RunId = runId });

If both must take part in one transaction, pass EF Core's current transaction to Dapper as well (for example, db.Database.CurrentTransaction?.GetDbTransaction()).

Performance is mostly about the SQL

Whichever you choose, a missing index or an N+1 pattern will cost far more than the difference between the libraries. Look at the SQL that actually runs, check execution plans for slow queries, and fetch only the columns and rows you need.

Related reading:

Comments

Popular posts from this blog

How to Read a SQL Server Execution Plan (Beginner's Guide)

SARGable Queries in SQL Server: Why Functions in WHERE Slow You Down

SQL Server Statistics Explained: Why Your Query Plans Go Wrong