Introduction
Entity Framework Core (EF Core) is a powerful ORM for .NET applications, allowing developers to interact with databases using LINQ instead of SQL. However, if not used carefully, EF Core queries can become slow, especially with large tables and complex relationships. The good news? There are many simple techniques that can help you improve EF Core performance significantly. In this article, you will learn practical tips—written in plain and natural language—to optimize your EF Core queries and make your .NET applications run faster.
Use AsNoTracking for Read-Only Queries
Tracking changes adds overhead. If you’re only reading data, disable tracking.
Example (Slow)
var users = await _context.Users.ToListAsync();
Optimized
var users = await _context.Users.AsNoTracking().ToListAsync();
Why It Helps
Reduces memory usage
Improves query execution speed
Recommended for all read-only operations
Select Only the Columns You Need (Projections)
Fetching entire entities loads unnecessary columns.
Slow Query
var users = await _context.Users.ToListAsync();
Efficient Query
var users = await _context.Users
.Select(u => new { u.Id, u.Name })
.ToListAsync();
Benefits
Smaller payload
Faster network transfer
Reduced materialization overhead
Use Pagination for Large Result Sets
Never return thousands of rows at once.
Example
var page = 1;
var pageSize = 20;
var users = await _context.Users
.Skip((page - 1) * pageSize)
.Take(pageSize)
.ToListAsync();
Why It Helps
Reduces memory usage
Prevents slow UI loading
Avoid N+1 Query Problems with Include
If you load related data in a loop, EF will run multiple queries.
Bad (N+1 queries)
var users = await _context.Users.ToListAsync();
foreach (var user in users)
{
var orders = user.Orders; // triggers additional queries
}
Good
var users = await _context.Users
.Include(u => u.Orders)
.ToListAsync();
Why It Matters
Prevents unnecessary round trips to the database
Use Filter Before Include (Important)
Filtering after Include loads unnecessary data.
Inefficient
var users = await _context.Users
.Include(u => u.Orders)
.Where(u => u.IsActive)
.ToListAsync();
Optimized
var users = await _context.Users
.Where(u => u.IsActive)
.Include(u => u.Orders)
.ToListAsync();
Why This Helps
Does not fetch extra records
Reduces memory and improves SQL execution
Index Database Columns Properly
Indexes drastically improve filtering and lookups.
Add Index in Entity
[Index(nameof(Email), IsUnique = true)]
public class User { ... }

Join the conversation! Your thoughts help the community grow.