Skip to main content
Login Register
Code2night
  • Home
  • Blog Archive
  • Learn
    • Tutorials
    • Videos
  • Interview Q&A
  • Resources
    • Cheatsheets
    • Tech Comparisons
  • Languages
    • Angular Angular js ASP.NET Asp.net Core ASP.NET Core, C# ASP.NET MVC ASP.NET Web Forms C C# C#, ASP.NET Core, Dapper
      C#, ASP.NET Core, Dapper, Entity Framework DotNet General Web Development HTML, CSS HTML/CSS Java JavaScript JavaScript, HTML, CSS JavaScript, Node.js Node.js
      Python Python 3.11, Pandas, SQL Python 3.11, SQL Python 3.11, SQLAlchemy Python 3.11, SQLAlchemy, SQL Python 3.11, SQLite React Security SQL Server TypeScript
  • Post Blog
  • Tools
    • Beautifiers
      JSON Beautifier HTML Beautifier XML Beautifier CSS Beautifier JS Beautifier SQL Formatter
      Dev Utilities
      JWT Decoder Regex Tester Diff Checker Cron Explainer String Escape Hash Generator Password Generator
      Converters
      Base64 Encode/Decode URL Encoder/Decoder JSON to CSV CSV to JSON JSON to TypeScript Markdown to HTML Number Base Converter Timestamp Converter Case Converter
      Generators
      UUID / GUID Generator Lorem Ipsum QR Code Generator Meta Tag Generator
      Image Tools
      Image Converter Image Resizer Image Compressor Image to Base64 PNG to ICO Background Remover Color Picker
      Text & Content
      Word Counter PDF Editor
      SEO & Web
      SEO Analyzer URL Checker World Clock
  1. Home
  2. Blog
  3. C#, ASP.NET Core, Dapper
  4. Implementing Asynchronous Data Access with Dapper in ASP.NET Core

Implementing Asynchronous Data Access with Dapper in ASP.NET Core

Date- Apr 12,2026 85
asynchronous dapper

Overview

Asynchronous programming is a programming paradigm that allows operations to run independently of the main application thread, enabling more efficient use of resources and improved application performance. In the context of web applications, especially those built using ASP.NET Core, asynchronous programming is essential when performing I/O-bound operations such as database access. Traditional synchronous database calls can lead to thread blocking, which degrades the performance of applications, particularly under heavy load.

Dapper is a lightweight, open-source ORM (Object-Relational Mapping) tool for .NET that simplifies data access by mapping database results to C# objects. By leveraging Dapper's capabilities in conjunction with asynchronous programming, developers can create highly responsive applications that manage database interactions efficiently. This approach is particularly beneficial in scenarios where applications require high concurrency, such as web APIs, e-commerce platforms, and real-time data-driven applications.

Prerequisites

  • C# Basics: Understanding of C# syntax and concepts.
  • ASP.NET Core: Familiarity with building web applications using ASP.NET Core.
  • SQL Knowledge: Basic understanding of SQL and relational databases.
  • Dapper Library: Awareness of how to install and use Dapper in .NET applications.
  • NuGet Package Manager: Knowledge of using NuGet to manage dependencies in ASP.NET Core.

Setting Up a New ASP.NET Core Project

To start implementing asynchronous data access with Dapper, we first need to set up a new ASP.NET Core project. This includes creating a web application and adding the necessary dependencies for Dapper.

dotnet new webapi -n AsyncDapperExample

This command creates a new ASP.NET Core Web API project named AsyncDapperExample. Next, navigate into the project directory:

cd AsyncDapperExample

Now, we will add the Dapper NuGet package to our project. Dapper can be installed using the following command:

dotnet add package Dapper

After installing Dapper, we need to ensure that our project can connect to a database. For this tutorial, we'll use SQLite as it is lightweight and easy to set up. Install the SQLite NuGet package:

dotnet add package Microsoft.Data.Sqlite

With our project set up, we are ready to implement asynchronous data access using Dapper.

Creating a Database and Data Model

Before we can access data asynchronously, we need to create a database and define a data model. For this example, we'll create a simple Product model representing products in an inventory system.

public class Product { public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } }

This Product class contains three properties: Id, Name, and Price. Next, we need to create a SQLite database and a Products table to store product data. In the Startup.cs file, we can add a method to initialize our database:

public void InitializeDatabase() { using (var connection = new SqliteConnection("Data Source=products.db")) { connection.Open(); var cmd = connection.CreateCommand(); cmd.CommandText = "CREATE TABLE IF NOT EXISTS Products (Id INTEGER PRIMARY KEY AUTOINCREMENT, Name TEXT, Price REAL);"; cmd.ExecuteNonQuery(); } }

This method opens a connection to a SQLite database file named products.db and creates a Products table if it does not already exist. To call this method during application startup, add the following line in the Configure method:

InitializeDatabase();

Now that our database and data model are set up, we can move on to implementing asynchronous data access with Dapper.

Implementing Asynchronous Data Access with Dapper

To demonstrate asynchronous data access, we will create a repository class that performs CRUD operations on the Products table using Dapper. We will focus on the GetAllProductsAsync method, which retrieves all products from the database asynchronously.

public class ProductRepository { private readonly string _connectionString; public ProductRepository(string connectionString) { _connectionString = connectionString; } public async Task> GetAllProductsAsync() { using (var connection = new SqliteConnection(_connectionString)) { await connection.OpenAsync(); var products = await connection.QueryAsync("SELECT * FROM Products"); return products; } } }

In this ProductRepository class, the constructor accepts a connection string. The GetAllProductsAsync method opens a connection to the database asynchronously using OpenAsync and retrieves all products using Dapper's QueryAsync method. This method returns an IEnumerable of Product objects.

Calling the Asynchronous Method from a Controller

Next, we will create a controller that uses the ProductRepository to fetch products asynchronously. In the Controllers folder, create a new controller named ProductsController:

[ApiController] [Route("api/[controller]")] public class ProductsController : ControllerBase { private readonly ProductRepository _repository; public ProductsController(ProductRepository repository) { _repository = repository; } [HttpGet] public async Task Get() { var products = await _repository.GetAllProductsAsync(); return Ok(products); } }

This controller defines a single Get action that calls GetAllProductsAsync to retrieve the products and returns them as a JSON response. The use of async/await ensures that the method is non-blocking, allowing for better scalability.

Edge Cases & Gotchas

While implementing asynchronous data access with Dapper, developers should be aware of common pitfalls that can lead to issues.

Connection Management

One common mistake is not properly managing database connections. Always ensure that connections are opened and closed correctly, especially in asynchronous methods.

// Incorrect approach - connection not disposed properly public async Task> GetProductsAsync() { var connection = new SqliteConnection(_connectionString); await connection.OpenAsync(); var products = await connection.QueryAsync("SELECT * FROM Products"); return products; } // Correct approach using (var connection = new SqliteConnection(_connectionString)) { await connection.OpenAsync(); var products = await connection.QueryAsync("SELECT * FROM Products"); return products; }

Handling Exceptions

Another important aspect is exception handling. Always wrap asynchronous calls in try-catch blocks to handle potential database exceptions gracefully.

try { var products = await _repository.GetAllProductsAsync(); return Ok(products); } catch (Exception ex) { return StatusCode(500, ex.Message); }

Performance & Best Practices

When working with asynchronous data access, following best practices can significantly enhance application performance.

Use Connection Pooling

Utilizing connection pooling can reduce the overhead of establishing connections by reusing existing ones. Ensure that your data source supports connection pooling and configure it appropriately in your connection string.

Minimize Database Calls

Reduce the number of database calls by fetching only the necessary data. Use pagination for large datasets to optimize performance.

Real-World Scenario: Implementing a Product API

Let’s tie everything together by implementing a simple product API that allows users to add, retrieve, and delete products.

[HttpPost] public async Task Create(Product product) { using (var connection = new SqliteConnection(_connectionString)) { await connection.OpenAsync(); var id = await connection.ExecuteAsync("INSERT INTO Products (Name, Price) VALUES (@Name, @Price)", product); return CreatedAtAction(nameof(Get), new { id }, product); } }

This Create action allows users to add new products to the database. The ExecuteAsync method is used for executing commands that do not return results.

[HttpDelete("{id}")] public async Task Delete(int id) { using (var connection = new SqliteConnection(_connectionString)) { await connection.OpenAsync(); var rowsAffected = await connection.ExecuteAsync("DELETE FROM Products WHERE Id = @Id", new { Id = id }); return rowsAffected > 0 ? NoContent() : NotFound(); } }

The Delete action removes a product based on its ID. It uses the same ExecuteAsync method to perform the delete operation.

Conclusion

  • Asynchronous data access with Dapper improves application responsiveness.
  • Proper connection management is crucial to avoid resource leaks.
  • Exception handling is essential for robust applications.
  • Follow best practices for optimal performance and scalability.
  • Real-world scenarios demonstrate practical usage of concepts learned.

S
Shubham Saini
Programming author at Code2Night — sharing tutorials on ASP.NET, C#, and more.
View all posts →

Related Articles

Using Dapper with ASP.NET Core: A Comprehensive Step-By-Step Guide
Apr 11, 2026
Dapper vs Entity Framework in ASP.NET Core: Choosing the Right Data Access Strategy
Apr 12, 2026
Debugging Dapper Queries in ASP.NET Core: Tips and Tricks
Apr 12, 2026
Optimizing Dapper Performance in ASP.NET Core Applications
Apr 11, 2026
Previous in C#, ASP.NET Core, Dapper
Debugging Dapper Queries in ASP.NET Core: Tips and Tricks
Buy me a pizza

Comments

🔥 Trending This Month

  • 1
    Complete Guide to C++ Classes: Explained with Examples 4,212 views
  • 2
    Implementing an End-to-End CI/CD Pipeline for ASP.NET Core… 366 views
  • 3
    Create Database and CRUD operation 3,388 views
  • 4
    Mastering TypeScript Utility Types: Partial, Required, Rea… 675 views
  • 5
    Responsive Slick Slider 23,373 views
  • 6
    Integrating Azure Cognitive Search into ASP.NET Core Appli… 156 views
  • 7
    Integrating Anthropic Claude API in ASP.NET Core for AI Ch… 141 views

On this page

🎯

Interview Prep

Ace your C#, ASP.NET Core, Dapper interview with curated Q&As for all levels.

View C#, ASP.NET Core, Dapper Interview Q&As

More in C#, ASP.NET Core, Dapper

  • Securing Dapper Queries in ASP.NET Core Against SQL Injectio… 126 views
View all C#, ASP.NET Core, Dapper posts →

Tags

AspNet C# programming AspNet MVC c programming AspNet Core C software development tutorial MVC memory management Paypal coding coding best practices data structures programming tutorial tutorials object oriented programming Slick Slider StripeNet
Free Download for Youtube Subscribers!

First click on Subscribe Now and then subscribe the channel and come back here.
Then Click on "Verify and Download" button for download link

Subscribe Now | 1770
Download
Support Us....!

Please Subscribe to support us

Thank you for Downloading....!

Please Subscribe to support us

Continue with Downloading
Be a Member
Join Us On Whatsapp
Code2Night

A community platform for sharing programming knowledge, tutorials, and blogs. Learn, write, and grow with developers worldwide.

Panipat, Haryana, India
info@code2night.com
Quick Links
  • Home
  • Blog Archive
  • Tutorials
  • About Us
  • Contact
  • Privacy Policy
  • Terms & Conditions
  • Guest Posts
  • SEO Analyzer
Dev Tools
  • JSON Beautifier
  • HTML Beautifier
  • CSS Beautifier
  • JS Beautifier
  • SQL Formatter
  • Diff Checker
  • Regex Tester
  • Markdown to HTML
  • Word Counter
More Tools
  • Password Generator
  • QR Code Generator
  • Hash Generator
  • Base64 Encoder
  • JWT Decoder
  • UUID Generator
  • Image Converter
  • PNG to ICO
  • SEO Analyzer
By Language
  • Angular
  • Angular js
  • ASP.NET
  • Asp.net Core
  • ASP.NET Core, C#
  • ASP.NET MVC
  • ASP.NET Web Forms
  • C
  • C#
  • C#, ASP.NET Core, Dapper
  • C#, ASP.NET Core, Dapper, Entity Framework
  • DotNet
  • General Web Development
  • HTML, CSS
  • HTML/CSS
  • Java
  • JavaScript
  • JavaScript, HTML, CSS
  • JavaScript, Node.js
  • Node.js
  • Python
  • Python 3.11, Pandas, SQL
  • Python 3.11, SQL
  • Python 3.11, SQLAlchemy
  • Python 3.11, SQLAlchemy, SQL
  • Python 3.11, SQLite
  • React
  • Security
  • SQL Server
  • TypeScript
© 2026 Code2Night. All Rights Reserved.
Made with for developers  |  Privacy  ·  Terms
Translate Page
We use cookies to improve your experience and analyze site traffic. By clicking Accept, you consent to our use of cookies. Privacy Policy
Accessibility
Text size
High contrast
Grayscale
Dyslexia font
Highlight links
Pause animations
Large cursor