articles

home / developersection / articles / what is cqrs and how would you implement it in a .net application?

What is CQRS and how would you implement it in a .NET application?

What is CQRS and how would you implement it in a .NET application?

Ravi Vishwakarma 314 16-Jun-2025

CQRS (Command Query Responsibility Segregation) is a software architecture pattern that separates the responsibilities of reading data (queries) and writing data (commands) into distinct models. This improves scalability, performance, and maintainability, especially in complex domains.

What is CQRS?

  • Commands: Modify state (create, update, delete). They return void or a simple result (e.g., success/failure).
  • Queries: Read data. They do not modify state and return data (DTOs).
  • Segregation: By splitting these concerns, each side can be optimized independently — e.g., read model could use denormalized views for performance.
What is CQRS and how would you implement it in a .NET application?

Why Use CQRS?

  • Clear separation of concerns (read vs write logic)
  • Easier to scale reads and writes independently
  • Enables complex business logic on writes without polluting queries
  • Simplifies event sourcing and audit trails

How to Implement CQRS in .NET

1. Define Command and Query Models

// Command
public class CreateStudentCommand
{
    public string Name { get; set; }
    public string Email { get; set; }
}

// Query
public class GetStudentByIdQuery
{
    public long Id { get; set; }
}

2. Create Handlers for Each

public class CreateStudentCommandHandler
{
    private readonly AppDbContext _context;

    public CreateStudentCommandHandler(AppDbContext context)
    {
        _context = context;
    }

    public async Task<bool> Handle(CreateStudentCommand command)
    {
        var student = new Student
        {
            Name = command.Name,
            Email = command.Email
        };

        _context.Students.Add(student);
        await _context.SaveChangesAsync();
        return true;
    }
}
public class GetStudentByIdQueryHandler
{
    private readonly AppDbContext _context;

    public GetStudentByIdQueryHandler(AppDbContext context)
    {
        _context = context;
    }

    public async Task<StudentDto> Handle(GetStudentByIdQuery query)
    {
        return await _context.Students
            .Where(s => s.Id == query.Id)
            .Select(s => new StudentDto
            {
                Id = s.Id,
                Name = s.Name,
                Email = s.Email
            })
            .FirstOrDefaultAsync();
    }
}

3. Optional: Use Mediator Pattern (e.g., with MediatR)

dotnet add package MediatR.Extensions.Microsoft.DependencyInjection

Define command and handler:

public record CreateStudentCommand(string Name, string Email) : IRequest<bool>;

public class CreateStudentCommandHandler : IRequestHandler<CreateStudentCommand, bool>
{
    private readonly AppDbContext _context;

    public CreateStudentCommandHandler(AppDbContext context) => _context = context;

    public async Task<bool> Handle(CreateStudentCommand request, CancellationToken cancellationToken)
    {
        _context.Students.Add(new Student { Name = request.Name, Email = request.Email });
        await _context.SaveChangesAsync();
        return true;
    }
}

CQRS + Event Sourcing (Advanced Use Case)

For even more decoupling, commands can raise events which are stored and later replayed to rebuild the system state. Libraries like EventStoreDB or NEventStore can be used.

What is CQRS and how would you implement it in a .NET application?

When to Use CQRS

Use CQRS When... Avoid CQRS When...
Complex domains with many business rules Simple CRUD apps
Need to scale reads/writes independently Small teams or tight deadlines
Heavy read operations with different needs One model suffices for read & write

 


c# c# 
Updated 16-Jun-2025

Ravi Vishwakarma is a dedicated Software Developer with a passion for crafting efficient and innovative solutions. With a keen eye for detail and years of experience, he excels in developing robust software systems that meet client needs. His expertise spans across multiple programming languages and technologies, making him a valuable asset in any software development project.

Leave Comment

Comments

Liked By