Skip to main content

Mastering PostgreSQL Connection with Dapper in .NET Core: A Step-by-Step Guide

 

If you're working with .NET Core and PostgreSQL, you might have come across Dapper, a popular micro ORM (Object-Relational Mapper) that provides a fast, lightweight way to interact with databases. This blog will guide you through the process of connecting your .NET Core application to a PostgreSQL database using Dapper—an elegant combination for developers looking for high performance without the complexity of full-fledged ORMs like Entity Framework.

Whether you're new to Dapper or PostgreSQL or just want a quick refresher, this blog will take you through the setup step by step. Let's dive into it!

Why Dapper + PostgreSQL? 🤔

Before we dive into the code, let's briefly cover why this combo makes sense:

  • Dapper is super fast because it doesn't abstract away SQL; you write your queries, giving you total control over performance.
  • PostgreSQL is one of the most powerful, open-source relational databases, well known for its scalability, performance, and advanced features.

The combination of Dapper's simplicity and performance with PostgreSQL's reliability makes for a robust solution in any .NET Core application.

Step 1: Set Up Your PostgreSQL Database 🛠️

First, if you haven’t already, you’ll need to have PostgreSQL installed on your machine or cloud service (AWS RDS, Azure PostgreSQL, etc.). Then create a sample database and table that we will use to test our connection.

CREATE DATABASE MyItemDB;

CREATE TABLE Items (
    Id SERIAL PRIMARY KEY,
    Name VARCHAR(100),
    Price DECIMAL(10, 2)
);

In this example, we'll be working with an Items table, which stores information about items such as Id, Name, and Price.

Step 2: Install Necessary NuGet Packages 📦

To work with PostgreSQL and Dapper, you’ll need the following NuGet packages:

  1. Npgsql - A PostgreSQL database provider for .NET.
  2. Dapper - The micro ORM.
  3. Microsoft.Extensions.Configuration - For managing your connection strings.

Install them via NuGet Package Manager or using the command line:

dotnet add package Npgsql
dotnet add package Dapper
dotnet add package Microsoft.Extensions.Configuration

Step 3: Configure PostgreSQL Connection String in appsettings.json 📝

In your appsettings.json file, add the PostgreSQL connection string. This is where you'll specify the credentials and database you're connecting to.

{
  "ConnectionStrings": {
    "PostgresConnection": "Host=localhost;Port=5432;Username=postgres;Password=mysecretpassword;Database=MyItemDB"
  }
}

Make sure to replace the values with your actual PostgreSQL credentials.

Step 4: Create a Model for Your Data 🏗️

Next, create a model that will represent the data from your Items table. This is the class that Dapper will map the data to.

{
  "ConnectionStrings": {
    "PostgresConnection": "Host=localhost;Port=5432;Username=postgres;Password=mysecretpassword;Database=MyItemDB"
  }
}

Step 5: Create the Repository Using Dapper and Npgsql 📄

Now, let's create the repository class that will handle database operations using Dapper.

using System.Collections.Generic;
using System.Data;
using System.Threading.Tasks;
using Dapper;
using Npgsql;
using Microsoft.Extensions.Configuration;

public class ItemRepository
{
    private readonly IConfiguration _configuration;
    private readonly string _connectionString;

    public ItemRepository(IConfiguration configuration)
    {
        _configuration = configuration;
        _connectionString = _configuration.GetConnectionString("PostgresConnection");
    }

    private IDbConnection Connection => new NpgsqlConnection(_connectionString);

    public async Task<IEnumerable<Item>> GetAllItemsAsync()
    {
        using (var connection = Connection)
        {
            string query = "SELECT * FROM Items";
            var items = await connection.QueryAsync<Item>(query);
            return items;
        }
    }

    public async Task<Item> GetItemByIdAsync(int id)
    {
        using (var connection = Connection)
        {
            string query = "SELECT * FROM Items WHERE Id = @Id";
            var item = await connection.QuerySingleOrDefaultAsync<Item>(query, new { Id = id });
            return item;
        }
    }

    public async Task<int> AddItemAsync(Item item)
    {
        using (var connection = Connection)
        {
            string query = "INSERT INTO Items (Name, Price) VALUES (@Name, @Price) RETURNING Id";
            var id = await connection.ExecuteScalarAsync<int>(query, item);
            return id;
        }
    }

    public async Task<int> UpdateItemAsync(Item item)
    {
        using (var connection = Connection)
        {
            string query = "UPDATE Items SET Name = @Name, Price = @Price WHERE Id = @Id";
            return await connection.ExecuteAsync(query, item);
        }
    }

    public async Task<int> DeleteItemAsync(int id)
    {
        using (var connection = Connection)
        {
            string query = "DELETE FROM Items WHERE Id = @Id";
            return await connection.ExecuteAsync(query, new { Id = id });
        }
    }
}

Breaking Down the Code:

  • We use the NpgsqlConnection to establish a connection with the PostgreSQL database.
  • Dapper's QueryAsync<T>() method is used for reading data, and ExecuteAsync() is used for insert/update/delete operations.
  • The repository follows the basic CRUD (Create, Read, Update, Delete) operations for our Item entity.

Step 6: Register Repository in Startup.cs 🛠️

In the Startup.cs file, register your repository class in the dependency injection (DI) container.

public void ConfigureServices(IServiceCollection services)
{
    services.AddScoped<ItemRepository>();
}

This allows your repository to be injected wherever needed in the application.

Step 7: Create a Controller to Test Your API 🎯

Now, create a basic API controller that will use the ItemRepository to handle requests.

using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Threading.Tasks;

[ApiController]
[Route("api/[controller]")]
public class ItemsController : ControllerBase
{
    private readonly ItemRepository _itemRepository;

    public ItemsController(ItemRepository itemRepository)
    {
        _itemRepository = itemRepository;
    }

    [HttpGet]
    public async Task<IEnumerable<Item>> GetItems()
    {
        return await _itemRepository.GetAllItemsAsync();
    }

    [HttpGet("{id}")]
    public async Task<ActionResult<Item>> GetItem(int id)
    {
        var item = await _itemRepository.GetItemByIdAsync(id);

        if (item == null)
        {
            return NotFound();
        }

        return item;
    }

    [HttpPost]
    public async Task<ActionResult<int>> AddItem(Item item)
    {
        var id = await _itemRepository.AddItemAsync(item);
        return CreatedAtAction(nameof(GetItem), new { id = id }, id);
    }

    [HttpPut("{id}")]
    public async Task<IActionResult> UpdateItem(int id, Item item)
    {
        if (id != item.Id)
        {
            return BadRequest();
        }

        await _itemRepository.UpdateItemAsync(item);

        return NoContent();
    }

    [HttpDelete("{id}")]
    public async Task<IActionResult> DeleteItem(int id)
    {
        await _itemRepository.DeleteItemAsync(id);
        return NoContent();
    }
}

Testing the API:

  • GET /api/items: Retrieve all items.
  • GET /api/items/{id}: Retrieve a specific item by ID.
  • POST /api/items: Add a new item.
  • PUT /api/items/{id}: Update an item.
  • DELETE /api/items/{id}: Delete an item.

Conclusion: You're Ready to Rock Dapper with PostgreSQL! 🎉

By following this guide, you've successfully connected a .NET Core application to a PostgreSQL database using Dapper. This lightweight yet powerful combination gives you control over your SQL queries without the overhead of a full ORM, while PostgreSQL provides you with the scalability and reliability your application needs.

In the next steps, you can start optimizing your queries, adding transaction handling, and exploring more advanced features like stored procedures. Stay tuned for more tips and tricks on building high-performance apps with .NET Core and PostgreSQL!

Coming Up Next: In future posts, we’ll dive into advanced query optimizations using Dapper and how to handle large datasets efficiently. Keep an eye out for that!

Comments

Popular posts from this blog

Implementing and Integrating RabbitMQ in .NET Core Application: Shopping Cart and Order API

RabbitMQ is a robust message broker that enables communication between services in a decoupled, reliable manner. In this guide, we’ll implement RabbitMQ in a .NET Core application to connect two microservices: Shopping Cart API (Producer) and Order API (Consumer). 1. Prerequisites Install RabbitMQ locally or on a server. Default Management UI: http://localhost:15672 Default Credentials: guest/guest Install the RabbitMQ.Client package for .NET: dotnet add package RabbitMQ.Client 2. Architecture Overview Shopping Cart API (Producer): Sends a message when a user places an order. RabbitMQ : Acts as the broker to hold the message. Order API (Consumer): Receives the message and processes the order. 3. RabbitMQ Producer: Shopping Cart API Step 1: Install RabbitMQ.Client Ensure the RabbitMQ client library is installed: dotnet add package RabbitMQ.Client Step 2: Create the Producer Service Add a RabbitMQProducer class to send messages. RabbitMQProducer.cs : using RabbitMQ.Client; usin...

How Does My .NET Core Application Build Once and Run Everywhere?

One of the most powerful features of .NET Core is its cross-platform nature. Unlike the traditional .NET Framework, which was limited to Windows, .NET Core allows you to build your application once and run it on Windows , Linux , or macOS . This makes it an excellent choice for modern, scalable, and portable applications. In this blog, we’ll explore how .NET Core achieves this, the underlying architecture, and how you can leverage it to make your applications truly cross-platform. Key Features of .NET Core for Cross-Platform Development Platform Independence : .NET Core Runtime is available for multiple platforms (Windows, Linux, macOS). Applications can run seamlessly without platform-specific adjustments. Build Once, Run Anywhere : Compile your code once and deploy it on any OS with minimal effort. Self-Contained Deployment : .NET Core apps can include the runtime in the deployment package, making them independent of the host system's installed runtime. Standardized Libraries ...

Clean Architecture: What It Is and How It Differs from Microservices

In the tech world, buzzwords like   Clean Architecture   and   Microservices   often dominate discussions about building scalable, maintainable applications. But what exactly is Clean Architecture? How does it compare to Microservices? And most importantly, is it more efficient? Let’s break it all down, from understanding the core principles of Clean Architecture to comparing it with Microservices. By the end of this blog, you’ll know when to use each and why Clean Architecture might just be the silent hero your projects need. What is Clean Architecture? Clean Architecture  is a design paradigm introduced by Robert C. Martin (Uncle Bob) in his book  Clean Architecture: A Craftsman’s Guide to Software Structure and Design . It’s an evolution of layered architecture, focusing on organizing code in a way that makes it  flexible ,  testable , and  easy to maintain . Core Principles of Clean Architecture Dependency Inversion : High-level modules s...