Blog
Mert Özen's blog posts on software development, backend, frontend, and DevOps.
Transactions in EF Core: SaveChanges, BeginTransaction and Savepoints
We watch SaveChanges' implicit transaction in the logs, turn several SaveChanges calls into one unit with BeginTransaction, roll back part of the work with savepoints, and look at the pitfalls of TransactionScope and retry strategies.
Concurrency in EF Core: Tokens, rowversion and DbUpdateConcurrencyException
We reproduce a lost update, set up optimistic concurrency with a concurrency token, use rowversion on SQL Server and a Guid version column on SQLite, and resolve DbUpdateConcurrencyException with a retry loop.
Raw SQL in EF Core: FromSqlRaw, FromSqlInterpolated, Keyless Entities and SQL Injection
We look at FromSqlRaw versus FromSqlInterpolated, the SQL produced when LINQ is composed on top, the SQL injection trap with $, ExecuteSql commands, keyless entities mapped to views, and calling stored procedures on SQL Server, all with real output.
EF Core in ASP.NET Core: AddDbContext, Scoped Lifetime, Factory and Pooling
We wire DbContext into ASP.NET Core with AddDbContext, watch the scoped lifetime through ContextId, solve the singleton and background service traps, and see with real output when AddDbContextFactory and AddDbContextPool help.
EF Core Performance Basics: N+1, Projection, AsNoTracking and Compiled Queries
We catch N+1 queries by counting commands, switch to DTO projections, measure the effect of tracking, indexes, split queries and compiled queries on SQLite, and monitor queries with TagWith and LogTo.
Global Query Filters in EF Core: Soft Delete, Multi-Tenancy and IgnoreQueryFilters
We build soft delete and multi-tenancy with HasQueryFilter, turn Remove into an UPDATE, switch filters off with IgnoreQueryFilters, and examine relationship pitfalls such as rows that vanish through an INNER JOIN on required navigations, with real SQL.
Inheritance Mapping in EF Core: TPH, TPT and When to Choose Which
How does EF Core turn a class hierarchy into tables? We compare TPH with its discriminator column and TPT with a table per type using real SQL output, and look at silent pitfalls like a subclass missing from the model.
Owned Types and Value Converters in EF Core: Addresses, Enums and Strongly Typed Ids
We tie identity-less values to their owner with OwnsOne and OwnsMany, store enums as text and wrap Ids in their own types. With real output we see a change lost for lack of a value comparer and an OwnsMany pitfall specific to SQLite.
EF Core Interceptors and Events: Audit Fields and Slow Query Logging
We fill CreatedAt and UpdatedAt automatically with a SaveChangesInterceptor, log queries over a threshold with a DbCommandInterceptor, and watch the change tracker live through SavingChanges and StateChanged events. We also see why nothing runs when you forget the async override.
Testing with EF Core: SQLite In-Memory and InMemory Provider Pitfalls
With real test output we see how the InMemory provider silently lets unique indexes, foreign keys and raw SQL slip through, and build realistic tests with SQLite in-memory. We cover the false green of asserting on the same context and the debate about abstracting DbContext, using the EF documentation's guidance.
EF Core and Architecture: Repositories, the Read Side of CQRS and Moving to Dapper
With real SQL we see how a generic repository silently moves the WHERE into memory, and discuss DbContext already being a unit of work. We finish the core block with an aggregate-specific repository, projections on the CQRS read side and Dapper sharing the same connection and transaction.
Legacy Projects: Moving from EF Core 3.1 and EF Core 5 to EF Core 6
The end of client evaluation in EF Core 3.0, FromSql split into FromSqlRaw/FromSqlInterpolated, many-to-many, filtered include and split queries in EF Core 5, how Nullable affects migrations when moving to EF Core 6, and support status.