Skip to content

Dapper Integration

Dapper is a simple and lightweight object mapper for .NET. A key feature of Dapper is its high performance compared to other ORMs.

While you can use Dapper as is in your modules there is also an integration package that simplifies creating repository classes using Dapper.

Implement a Dapper Repository

The best way to interact with Dapper is to create a repository class that abstracts your Dapper database operations. The following example creates a new repository class that works with the People table:

public class PersonDapperRepository : DapperRepository<MyAppDbContext>, ITransientDependency
{
    public PersonDapperRepository(IDbContextProvider<MyAppDbContext> dbContextProvider)
        : base(dbContextProvider)
    {
    }

    public virtual async Task<List<string>> GetAllPersonNamesAsync()
    {
        var dbConnection = await GetDbConnectionAsync();

        return (await dbConnection.QueryAsync<string>(
            "select Name from People",
            transaction: await GetDbTransactionAsync())
        ).ToList();
    }

    public virtual async Task<int> UpdatePersonNamesAsync(string name)
    {
        var dbConnection = await GetDbConnectionAsync();
        return await dbConnection.ExecuteAsync(
            "update People set Name = @NewName",
            new { NewName = name },
            await GetDbTransactionAsync()
        );
    }
}

Let's examine this class:

  • It inherits from the DapperRepository class, which provides useful methods and properties for database operations. It also implements the IUnitOfWorkEnabled interface, so ABP makes the database connection (and transaction if requested) available in the method body by implementing dynamic proxies (a.k.a. interception).
  • It gets an IDbContextProvider<MyAppDbContext> object where MyAppDbContext is type of your Entity Framework Core DbContext class. It should be configured as explained in the EF Core document. If you've created by ABP's startup template, then it should already be configured.
  • The GetAllPersonNamesAsync and UpdatePersonNamesAsync method's been made virtual. That's needed to make the interception process working.
  • We've used the GetDbConnectionAsync and GetDbTransactionAsync methods to obtain the current database connection and transaction (that is managed by ABP's Unit of Work system).

Then you can inject PersonDapperRepository to any service to perform these database operations. If you want to implement a layered solution, we suggest to introduce an IPersonDapperRepository interface in your domain layer, implement it in your database later, then inject the interface to use the repository service.

Source Code

You can find the full source code of the demo application here.