Skip to content

EF Core DbContext — Complete Guide

DodaTech Updated 2026-06-24 2 min read

In this tutorial, you'll learn about EF Core DbContext. We cover key concepts, practical examples, and best practices.

You create a new DbContext instance manually every time you need the database, forgetting to dispose or misconfiguring the connection. Proper DbContext lifecycle management is critical for performance and correctness in Entity Framework Core.

Wrong

public class ProductService
{
    public List<Product> GetProducts()
    {
        using var ctx = new AppDbContext(); // Manual instantiation
        return ctx.Products.ToList();
    }
}

Output: Works. But the connection string is hardcoded, no DI, no pooling.

public class ProductService
{
    private readonly AppDbContext _ctx;

    public ProductService(AppDbContext ctx) // DI injection
    {
        _ctx = ctx;
    }

    public List<Product> GetProducts()
    {
        return _ctx.Products.ToList();
    }
}

Registration in Program.cs:

builder.Services.AddDbContext<AppDbContext>(options =>
    options.UseSqlServer(connectionString));

For high-throughput scenarios, use pooling:

builder.Services.AddDbContextPool<AppDbContext>(options =>
    options.UseSqlServer(connectionString));

Prevention

  • Register DbContext with DI using AddDbContext.
  • Inject the context via constructor — never manually instantiate.
  • Use AddDbContextPool for web applications to reuse context instances.
  • Keep context lifetime scoped to the HTTP request or unit of work.
  • Override OnConfiguring only as a fallback — prefer DI configuration.
  • Avoid adding too many tracked entities in a single context instance.
  • Dispose the context when done — DI containers handle scope disposal.

Common Mistakes with core db context

  1. Non-exhaustive pattern matches that compile with warnings then crash at runtime
  2. Misunderstanding that String is [Char] with poor performance for large text operations
  3. Using foldl instead of foldl' causing stack overflow on large lists

These mistakes appear frequently in real-world EF code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.

Practice Exercise

Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.

This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.

FAQ

Should I use AddDbContext or AddDbContextPool?

AddDbContextPool reuses context instances and is recommended for web applications. It improves performance by reducing initialization overhead. The pool size is configurable (default 128). Use AddDbContext for long-lived or non-web scenarios.

Can I use multiple DbContext types?

Yes. Register each with AddDbContext<TContext> and inject the specific one you need. Each context type has its own pool and configuration. This is useful for bounded contexts or multi-database applications.

How long should a DbContext live?

Typically per HTTP request in web apps. For background services, create a new scope per logical operation. Short-lived contexts use less memory and reduce the chance of stale data. Dispose contexts as soon as possible.

Learn more about DbContext patterns at DodaTech.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro