Welcome To Learn Dapper

This site is for developers who want to learn how to use Dapper - the micro ORM produced by the people behind Stackoverflow.

What is Dapper?

Dapper is a popular simple object mapping tool. It is designed primarily to be used in scenarios where you want to work with data in a strongly typed fashion - as business objects in a .NET application, but don't want to spend hours writing code to map query results from ADO.NET data readers to instances of those objects. Dapper is an open source project under the Apache license. It is available as a Nuget package and has been downloaded over 16 million times.

Is Dapper an ORM?

Dapper falls into a family of tools known as micro-ORMs. These tools perform only a subset of the functionality of full-blown Object Relations Mappers, such as Entity Framework Core. Features vary by product. The following table provides a general idea of the capabilities that you can expect to find in a micro ORM compared to an ORM:

Micro ORM ORM
Map queries to objects
Caching results
Change tracking 1
SQL generation 2
Identity management
Association management
Lazy loading
Unit of work support
Database migrations

Dapper concentrates its efforts on the O and M of ORM - Object Mapping.

[1] Some extensions have been added to Dapper that provide minimal change tracking capability [2] Dapper actually does generate SQL, but in a limited fashion.

When Should You Use Dapper?

When deciding whether to use Dapper or not, one should bear in mind the primary reason for its existence - performance. The original developers of Dapper were using Entity Framework Core's predecessor - the short-lived Linq to SQL. They found that query performance wasn't good enough for the increasing traffic that the site in question (Stackoverflow) was experiencing, so they wrote their own micro ORM.

Dapper is therefore a good choice in scenarios where read-only data changes frequently and is requested often. It is particularly good in stateless scenarios (e.g. the web) where there is no need to persist complex object graphs in memory for any duration.

Dapper does not translate queries written in .NET languages to SQL like a full blown ORM. So you need to be comfortable writing queries in SQL, or have someone write them for you.

Dapper has no real expectation about the schema of your database. It is not reliant on conventions in the same way as Entity Framework Core, so Dapper is also a good choice where the structure of the database isn't particularly normalised.

Dapper works with an ADO.NET IDbConnection object, which means that it will work with any database system for which there is an ADO.NET provider.

There is no reason why you cannot use both an ORM and a micro ORM in the same project.

What does Dapper actually do?

Here is some standard ADO.NET code for retrieving data from a database and materialising it as a collection of Product objects:

var sql = "select * from products";
var products = new List<Product>();
using (var connection = new SqlConnection(connString))
{
    connection.Open();
    using (var command = new SqlCommand(sql, connection))
    {
        using (var reader = command.ExecuteReader())
        {
            var product = new Product
            {
                ProductId = reader.GetInt32(reader.GetOrdinal("ProductId")),
                ProductName = reader.GetString(reader.GetOrdinal("ProductName")),
                SupplierId = reader.GetInt32(reader.GetOrdinal("SupplierId")),
                CategoryId = reader.GetInt32(reader.GetOrdinal("CategoryId")),
                QuantityPerUnit = reader.GetString(reader.GetOrdinal("QuantityPerUnit")),
                UnitPrice = reader.GetDecimal(reader.GetOrdinal("UnitPrice")),
                UnitsInStock = reader.GetInt16(reader.GetOrdinal("UnitsInStock")),
                UnitsOnOrder = reader.GetInt16(reader.GetOrdinal("UnitsOnOrder")),
                ReorderLevel = reader.GetInt16(reader.GetOrdinal("ReorderLevel")),
                Discontinued = reader.GetBoolean(reader.GetOrdinal("Discontinued")),
                DiscontinuedDate = reader.GetDateTime(reader.GetOrdinal("DiscontinuedDate"))
            };
            products.Add(product);
        }
    }
}

At its most basic level, Dapper replaces the highlighted block of assignment code in the example above with the following:

products = connection.Query<Product>(sql);

Dapper also takes care of creating the command and opening the connection if needed. If all you ever use Dapper for is for managing basic assignment like this, it will save you hours of time. In fact, Dapper is capable of doing quite a bit more.

Where can you get Dapper?

Dapper is available from Nuget. It is compliant with .NET Standard 2.0 which means that it can be used in .NET applications that target the full framework and .NET Core. You can install the latest version using the following command with the .NET CLI:

dotnet add package Dapper

or this command from the Package Manager Console in Visual Studio:

install-package Dapper

The source code for Dapper is available on GitHub.

Last updated: 21/05/2019 13:52:49