8 minlesson

DbContext Overview

DbContext Overview

The DbContext class is the central piece of Entity Framework Core. It represents a session with the database and provides the API you use to query, insert, update, and delete data. Every EF Core application has at least one DbContext.

What Is DbContext?

DbContext is a class from the Microsoft.EntityFrameworkCore namespace that you inherit from to create your own database context. Think of it as a bridge between your C# domain classes and the underlying database.

csharp
1using Microsoft.EntityFrameworkCore;
2
3public class AppDbContext : DbContext
4{
5 public DbSet<Product> Products => Set<Product>();
6 public DbSet<Category> Categories => Set<Category>();
7
8 protected override void OnConfiguring(DbContextOptionsBuilder options)
9 => options.UseSqlite("Data Source=app.db");
10}

This small class tells EF Core three things:

  1. Which entities exist - Products and Categories are database tables
  2. How to connect - Use a SQLite database file called app.db
  3. How to map - EF Core uses conventions to map Product properties to columns

Responsibilities of DbContext

DbContext handles several responsibilities behind the scenes:

ResponsibilityDescription
Connection managementOpens and closes database connections as needed
Query translationConverts LINQ expressions into SQL
Change trackingMonitors loaded entities for modifications
Saving dataGenerates INSERT, UPDATE, DELETE SQL from tracked changes
Caching metadataStores entity-to-table mappings for performance
Transaction managementWraps SaveChanges in a transaction automatically

Creating a Basic DbContext

To create a DbContext, you need three ingredients:

  1. A class that inherits from DbContext
  2. One or more DbSet<T> properties for your entities
  3. A database connection configuration
csharp
1using Microsoft.EntityFrameworkCore;
2
3public class SchoolContext : DbContext
4{
5 public DbSet<Student> Students => Set<Student>();
6 public DbSet<Course> Courses => Set<Course>();
7
8 protected override void OnConfiguring(DbContextOptionsBuilder options)
9 => options.UseSqlite("Data Source=school.db");
10}

The DbSet<T> properties are your main interaction points. Each DbSet<T> maps to a table in the database and provides methods for querying and modifying that table's data.

Using DbContext

A typical usage pattern follows these steps:

csharp
1// 1. Create a context instance
2using var context = new SchoolContext();
3
4// 2. Ensure the database exists
5await context.Database.EnsureCreatedAsync();
6
7// 3. Add new data
8var student = new Student { Name = "Alice", Email = "alice@example.com" };
9context.Students.Add(student);
10await context.SaveChangesAsync();
11
12// 4. Query data
13var students = await context.Students
14 .Where(s => s.Name.Contains("Ali"))
15 .ToListAsync();
16
17// 5. Update data
18student.Email = "alice.new@example.com";
19await context.SaveChangesAsync();
20
21// 6. Delete data
22context.Students.Remove(student);
23await context.SaveChangesAsync();

Notice the using statement on line 2. DbContext implements IDisposable and should always be disposed when you are done with it. This releases the database connection and other resources.

Configuration Approaches

There are two common ways to configure your DbContext:

Override OnConfiguring

Used in console applications and simple scenarios:

csharp
1protected override void OnConfiguring(DbContextOptionsBuilder options)
2 => options.UseSqlite("Data Source=app.db");

Constructor Injection

Used in ASP.NET Core and applications with dependency injection:

csharp
1public class AppDbContext : DbContext
2{
3 public AppDbContext(DbContextOptions<AppDbContext> options)
4 : base(options) { }
5
6 public DbSet<Product> Products => Set<Product>();
7}

The options are then provided during service registration:

csharp
1builder.Services.AddDbContext<AppDbContext>(options =>
2 options.UseSqlite("Data Source=app.db"));

DbContext and the Unit of Work Pattern

DbContext implements the Unit of Work pattern. It collects all changes you make during a business operation and applies them to the database in a single transaction when you call SaveChanges.

1┌──────────────────────────────────────────┐
2│ DbContext │
3│ │
4│ Add(student) ──┐ │
5│ Update(course) ──┼── SaveChanges() ──►│ BEGIN TRANSACTION
6│ Remove(enrollment)─┘ │ INSERT INTO Students...
7│ │ UPDATE Courses...
8│ │ DELETE FROM Enrollments...
9│ │ COMMIT
10└──────────────────────────────────────────┘

If any operation fails during SaveChanges, the entire transaction is rolled back, keeping your database consistent.

Key Takeaways

  • DbContext is your main entry point for all database operations in EF Core
  • It manages connections, translates LINQ to SQL, tracks changes, and handles transactions
  • Each DbSet<T> property maps to a database table
  • Always dispose your DbContext when finished (use using statements)
  • DbContext implements the Unit of Work pattern, batching all changes into a single transaction

In the next lesson, you'll learn how to define the entity classes that your DbContext works with.