Introduction

In the .NET ecosystem, Entity Framework Core (EF Core) and Dapper are two of the most popular data access technologies.
Both are powerful, but they serve different purposes.

In this article, we’ll cover:

What is EF Core?

Entity Framework Core is a full-featured ORM (Object Relational Mapper).
It allows developers to work with databases using C# objects instead of raw SQL.

Key Features of EF Core

✔ LINQ-based querying
✔ Change tracking
✔ Migrations
✔ Relationship management
✔ Faster development for CRUD apps

When EF Core is a Good Choice

What is Dapper?

Dapper is a Micro ORM developed by Stack Overflow.
It is essentially a high-performance wrapper over ADO.NET.

Key Features of Dapper

✔ Extremely fast
✔ Full SQL control
✔ Excellent support for stored procedures
✔ Minimal abstraction

When Dapper is a Good Choice

FeatureEF CoreDapper
TypeFull ORMMicro ORM
PerformanceModerateVery High
SQL ControlLimitedFull
Learning CurveMediumLow
Stored ProceduresSupportedExcellent
Change TrackingYesNo
Best Use CaseBusiness appsPerformance-critical apps

EF Core Example

Code
public class Customer
{
    public int Id { get; set; }
    public string Name { get; set; } = string.Empty;
    public decimal Balance { get; set; }
}

DbContext

Code
public class AppDbContext : DbContext
{
    public DbSet<Customer> Customers => Set<Customer>();

    public AppDbContext(DbContextOptions<AppDbContext> options)
        : base(options) { }
}

Program.cs

Code
builder.Services.AddDbContext<AppDbContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("Default")));

Query Using EF Core

Code
app.MapGet("/customers", async (AppDbContext db) =>
{
    return await db.Customers
                   .Where(c => c.Balance > 1000)
                   .ToListAsync();
});

Pros

Cons

Dapper Example

Repository

Code
public class CustomerRepository
{
    private readonly IDbConnection _db;

    public CustomerRepository(IConfiguration configuration)
    {
        _db = new SqlConnection(configuration.GetConnectionString("Default"));
    }

    public async Task<IEnumerable<Customer>> GetCustomersAsync()
    {
        var sql = """
                  SELECT Id, Name, Balance
                  FROM Customers
                  WHERE Balance > @Balance
                  """;

        return await _db.QueryAsync<Customer>(
            sql,
            new { Balance = 1000 }
        );
    }
}

Register Service

Code
builder.Services.AddScoped<CustomerRepository>();

Minimal API Endpoint

Code
app.MapGet("/customers-dapper", async (CustomerRepository repo) =>
{
    return await repo.GetCustomersAsync();
});

Pros

Stored Procedure Example with Dapper

Code
public async Task<Customer?> GetCustomerByIdAsync(int id)
{
    return await _db.QueryFirstOrDefaultAsync<Customer>(
        "usp_GetCustomerById",
        new { Id = id },
        commandType: CommandType.StoredProcedure
    );
}

Which One Should You Use?

Use EF Core if:

Use Dapper if: