Ha Doan
3 min readDec 29, 2019

CQRS pattern with C#

1. What is CQRS pattern

CQRS is Command Query Responsibility Segregation, first introduced by Greg Young and Udi Dahan, fundamentally CQRS contains two parts

  • Commands: change the state of an object or system, sometimes called as modifiers or mutators. Normally we use for change data of a data table in relationship database (e.g change product name,…)
  • Queries: return results and do not change the state of an object (e.g return product information, product list, …)

Pros

  • Independent scaling: most of the application consumes lots of queries, so we can create dedicated service for queries and scale-up query service to optimize performance.
  • Optimized data schemas: can separately optimized database schema for queries and updates.
  • Security: It’s easier to ensure that only the right domain entities are performing writes on the data.
  • Separation of concerns: Segregating the read and write sides can result in models that are more maintainable and flexible. Most of the complex business logic goes into the write model. The read model can be relatively simple.
  • Simpler queries: be design optimized schema for queries, the application can avoid complex join when querying.

Cons

  • Complexity: Application design will be more complex and in a real-world application, we need to add more patterns (e.g Event Sourcing) to adapt business needs.
  • Messaging: Use messaging to process commands and publish update events, and the application must handle message failures or duplicate messages.
  • Eventual consistency. If you separate the read and write databases, the read data may be stale or out-dated. The read model store must be updated to reflect changes to the write model store, and it can be difficult to detect when a user has issued a request based on stale read data.

2. When to use CQRS

  • Task-based user interfaces where users are guided through a complex process as a series of steps or with complex domain models
  • Optimize for performance when the number of reads is much greater than the number of writes. In this scenario, you can scale out the read model, but run the write model on just a few instances.
  • 2 separate teams, one team focus on the read model and other team focus on write model
  • Integration with other systems by Event Sourcing.

3. Sample

In this sample, I will use MediatR as messaging framework and EF Core In-Memory database

  • There are 2 tables: Todo — store todo list and TodoSummary — store summary of today todo list
  • Create AddTodoCommand and AddTodoCommandHandler
  • Create CompleteCommand and CompleteCommandHandler
  • Call Commands from Controller
  • Query data from the controller

Results from Postman

You can also see full source code at https://github.com/hadoan/handon-blogs/tree/master/CqrsTodo

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

No responses yet

Write a response