Dapper: The Minimalist ORM Powering High-Performance .NET Data Access

Dapper is a lightweight Object-Relational Mapper (ORM) for the .NET ecosystem. Developed by the Stack Overflow engineering team, it provides a fluent, low-ceremony way to interact with databases while retaining full command over SQL statements. Its reputation for speed and simplicity has made it a popular choice among .NET developers.

Core Characteristics

  1. Lightweight footprint: Dapper adds negligible overhead, making it one of the fastest ORMs available.
  2. SQL-first philosophy: Rather than abstracting SQL behind query builders, Dapper encourages you to write raw, optimized queries.
  3. Dynamic mapping: Results can be mapped to strongly-typed objects or dynamic types without prior schema definition.
  4. Async-first: The library exposes async methods for non-blocking database operations.
  5. Minimal API surface: The API is deliberately small, reducing the learning curve and keeping code straightforward.

Getting Started

Install Dapper via NuGet:

dotnet add package Dapper

Basic Usage Examples

Consider a Person entity and a matching People table:

public class Person
{
    public int Id { get; set; }
    public string FullName { get; set; }
    public string EmailAddress { get; set; }
}

The snippets below illustrate typical CRUD operations with Dapper.

Retrieving Data

using System.Data.SqlClient;
using Dapper;

var connectionString = "Server=.;Database=Demo;Trusted_Connection=true;";

using (var conn = new SqlConnection(connectionString))
{
    // Single row
    var person = conn.QueryFirstOrDefault<Person>(
        "SELECT * FROM People WHERE Id = @Id", new { Id = 1 });

    // Multiple rows with filtering
    var people = conn.Query<Person>(
        "SELECT * FROM People WHERE EmailAddress LIKE @Domain",
        new { Domain = "%@example.com" });

    // Dynamic result (no predefined class)
    var dynamicResults = conn.Query(
        "SELECT * FROM People WHERE FullName = @Name",
        new { Name = "John Doe" }).ToList();
}

Inserting a Record

using (var conn = new SqlConnection(connectionString))
{
    var newId = conn.ExecuteScalar<int>(
        "INSERT INTO People (FullName, EmailAddress) VALUES (@FullName, @EmailAddress); " +
        "SELECT CAST(SCOPE_IDENTITY() AS INT);",
        new { FullName = "Alice Smith", EmailAddress = "alice@example.com" });
}

Updating Data

using (var conn = new SqlConnection(connectionString))
{
    var affected = conn.Execute(
        "UPDATE People SET FullName = @FullName WHERE Id = @Id",
        new { FullName = "Bob Johnson", Id = 2 });
}

Deleting a Row

using (var conn = new SqlConnection(connectionString))
{
    var deletedCount = conn.Execute(
        "DELETE FROM People WHERE Id = @Id",
        new { Id = 3 });
}

Why Chooce Dapper?

Dapper strikes a balance between the convenience of an ORM and the control of raw ADO.NET. It eliminates boilerplate code for mapping and connection management, yet doesn't hide the SQL. This makes it ideal for performance-sensitive applications or teams that prefer explicit, predictable database interactions. The examples above show how terse and expressive Dapper code can be for everyday database tasks.

Tags: Dapper .NET ORM C# sql

Posted on Thu, 08 Oct 2026 16:43:47 +0000 by nz_mitch