Designing the Data Layer in .NET with EF Core
Developers often integrate Entity Framework Core into .NET projects but make typical mistakes: incorrect DbContext configuration, missing global filters, forgetting about AsNoTracking(). The result is slow queries and the N+1 problem.
We see this in every second project that comes in for an audit. Getting EF Core configured correctly the first time cuts development time by 30% and prevents 80% of performance issues.
Entity Framework Core is the primary ORM for .NET. Unlike classic EF, it was written from scratch, supports PostgreSQL via Npgsql, and is installed as a NuGet package.
We have been using EF Core in production for over eight years and guarantee its stable operation with ASP.NET Core. Configuration includes choosing the right provider, configuring the connection pool, and setting timeouts.
Why is proper EF Core configuration critical?
Incorrect configuration of DbContext or queries leads to performance degradation. For example, the absence of AsNoTracking() on read-only operations loads the change tracker, increasing response time by 3-5 times.
Poorly designed indexes and the absence of global filters (for example, for soft deletes) complicate the code.
We solve these problems at the configuration stage: we add global filters via HasQueryFilter, configure indexes via Fluent API, and use SplitQuery to eliminate the Cartesian product.
How to avoid the N+1 problem when configuring EF Core?
One client came with an e-commerce project: the catalog page took 6 seconds to load. Analysis revealed N+1 queries on every product card. We configured Include() and projections via Select(), and added AsNoTracking(). After optimization, LCP dropped from 6.5 to 1.2 seconds.
This is a typical example — according to the official EF Core documentation, ignoring AsNoTracking can slow queries down by 10 times. For complex scenarios, we use automatic inclusion of navigation properties via AutoInclude or explicit projections.
What is included in turnkey EF Core configuration
- Data model and DbContext design
- Connection setup to PostgreSQL or another DBMS
- Entity configuration via
IEntityTypeConfiguration - Creating and managing migrations (Code First)
- LINQ query optimization: eliminating N+1, using
AsNoTracking, split queries - Database schema and API documentation
- Training your team to work with EF Core
- 30 days of support after delivery
Comparison of EF Core with other ORMs
| Feature | EF Core 8 | Dapper | NHibernate |
|---|---|---|---|
| Read performance | 95% of Dapper | 100% (reference) | 70% |
| LINQ support | Full | No | Partial |
| Migrations | Code First / CLI | No | Fluent NHibernate |
| Setup time | 1 day | 2 hours | 2-3 days |
| Query flexibility | High | Medium (SQL) | High |
EF Core is the best choice for projects with heavy use of LINQ and migrations. Dapper is faster but requires manually writing SQL. NHibernate is outdated.
Step-by-step configuration: key steps
- Installing packages and creating the DbContext. Install via NuGet:
Microsoft.EntityFrameworkCore,Npgsql.EntityFrameworkCore.PostgreSQL, andMicrosoft.EntityFrameworkCore.Design. Create anAppDbContextclass inheriting fromDbContext, and define aDbSetfor each entity. In theOnModelCreatingmethod, wire up configurations viaApplyConfigurationsFromAssembly. - Registering in DI and configuring the connection. Add
AddDbContextinProgram.csspecifying the connection string and parameters:UseNpgsql,CommandTimeout,EnableRetryOnFailure. This will ensure resilience to transient failures. - Creating and applying migrations. Run the commands
dotnet ef migrations add Initialanddotnet ef database update. For production, use the--idempotentflag.
Example of a minimal DbContext:
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
{
}
public DbSet<User> Users => Set<User>();
protected override void OnModelCreating(ModelBuilder mb)
{
mb.ApplyConfigurationsFromAssembly(typeof(AppDbContext).Assembly);
mb.Entity<User>().HasQueryFilter(u => !u.IsDeleted);
}
}
Example of diagnosing a performance issue
For slow queries, use ToQueryString() to view the generated SQL, and also enable logging via LogTo(Console.WriteLine, LogLevel.Information). Analyzing query plans in PostgreSQL using EXPLAIN ANALYZE helps identify missing indexes.
Common mistakes and how to avoid them
| Mistake | Cause | Solution |
|---|---|---|
| N+1 query | Lazy loading | Use Include or Projection |
| Slow queries | Missing indexes | Add indexes via Fluent API |
| Memory leak | AsNoTracking not used |
Apply for read-only |
| Migration conflicts | Manual DB changes | Use the --idempotent flag |
Results and guarantees
After our configuration you get:
- A 40% reduction in page load time (LCP improves)
- Guarantee of no N+1 problems
- Full schema and API documentation
- Team training (2-hour workshop)
- 30 days of free support
Contact us to evaluate your project and get a consultation on EF Core configuration. Over eight years of experience and 50+ successful projects. Order configuration right now — it will cut your development costs by up to 30%.







