Data access is where most .NET apps win or lose their performance budget. EF Core isn't slow — three default behaviours are.
I took a 1,000-row product list endpoint and pulled it down from 38 ms to 8 ms using real production benchmarks, one perf lever at a time.
The benchmark ladder
| Approach | Mean | Allocated |
|---|---|---|
| Tracked entity (default) | 38.2 ms | 4.1 MB |
AsNoTracking() |
24.7 ms | 1.8 MB |
| Projection to DTO | 12.1 ms | 0.6 MB |
EF.CompileAsyncQuery |
9.8 ms | 0.4 MB |
| Dapper hand-tuned SQL | 8.4 ms | 0.3 MB |
Raw SqlDataReader
|
7.9 ms | 0.2 MB |
The single biggest win — projection
Stop returning entities. Project to DTOs that contain only the columns your endpoint actually uses.
public record ProductListDto(
Guid Id, string Name, decimal Price,
string CategoryName, int ReviewCount);
var products = await db.Products
.Select(p => new ProductListDto(
p.Id, p.Name, p.Price,
p.Category.Name,
p.Reviews.Count()))
.ToListAsync();
EF generates SELECT for the four columns you asked for instead of forty. One rewrite — 85% fewer allocations and 50% faster.
The hybrid pattern
In 2026 you don't have to pick EF Core or Dapper. They share the same DbConnection:
public class OrderService(AppDbContext db)
{
// Write: EF Core — tracking, validation, audit.
public Task<Guid> CreateAsync(CreateOrder cmd) { /* ... */ }
// Hot read: Dapper, on EF's connection.
public async Task<IReadOnlyList<SalesRow>> DailyAsync()
{
var conn = db.Database.GetDbConnection();
return (await conn.QueryAsync<SalesRow>("SELECT ...")).ToList();
}
}
EF for writes and most reads. Dapper for the 10% of queries where every millisecond counts. Same project, same connection, no architectural cost.
Watch the 3-min walkthrough
Go deeper
The full written guide has the production benchmarks, the decision matrix, the pull-request checklist, ExecuteUpdateAsync, AsSplitQuery, cursor pagination, multi-result-set queries, and the full EF + Dapper hybrid pattern with code:
https://prepstack.co.in/blog/dotnet-data-access-ef-core-linq-dapper-performance-guide
Which single perf lever in your .NET data layer gave you the biggest production speedup? Share your war story in the comments.
Top comments (0)