Saving a payment and then publishing "PaymentSucceeded" is two writes to two systems. One of them will eventually fail. The outbox pattern turns it into one write, with runnable EF Core code.
A decimal doesn't know its currency, its precision or how to split itself. A small Money type does, and it turns a whole class of silent bugs into loud ones. Runnable C# 14 and EF Core code.
A balance column tells you a number. A ledger tells you why. How to make recorded transactions the single source of truth for a wallet, with runnable EF Core code.
An idempotency key turns "the client retried" from a duplicate payment into a harmless replay. Here is a small, runnable ASP.NET Core implementation and the trade-offs behind it.
Use EF Core where you change data and Dapper where you read it for a screen or a report. Here is why the split works, with runnable code that shares one connection.
Two withdrawals read the same balance and both succeed: that's a race condition. Three ways to stop it in EF Core (rowversion, an atomic update, and a row lock) and when to use each.