DbContext is the Entity Framework Core object that defines which entities belong to a data model and coordinates access to them. Create a class that inherits from DbContext, then expose an entity through a DbSet property. For example, a context with DbSet<Book> Books lets EF Core recognize Book as an entity; an Id property becomes its primary key by convention. section 5.2
Listing 5.3 A DbContext that holds the Book class
using Microsoft.EntityFrameworkCore;
namespace ManningBooks;
public class CatalogContext : DbContext #1
{
public DbSet<Book> Books { get; set; } #2
protected override void OnConfiguring(DbContextOptionsBuilder options)
=> options.UseInMemoryDatabase("ManningBooks"); #3
}
A minimal context declares the Books set and selects an EF Core in-memory database in OnConfiguring. section 5.2
Use a context to add entities, call SaveChanges to persist them, and query its DbSet with LINQ. For related data, Include loads ratings alongside a book; FirstOrDefaultAsync performs the lookup asynchronously. A context is lightweight but not thread-safe: create and dispose one for each request or independent operation rather than sharing one across parallel tasks. section 5.2 section 5.3
One context per lookup
A lookup creates a CatalogContext with using, queries dbContext.Books.Include(b => b.Ratings).FirstOrDefaultAsync(b => b.Title == title), then disposes the context. Separate calls can run concurrently without making them share a DbContext. section 5.3
In an ASP.NET Core API, register the context with AddDbContext<CatalogContext>() and accept it in a controller constructor. Dependency injection supplies the same context throughout one request and disposes it when the response finishes. A read-only controller query can use AsNoTracking. For configurable database setup, accept DbContextOptions in the context constructor and configure SQLite when registering it instead of fixing the provider inside the context. section 5.4.1 section 9.1
Listing 9.2 Using Sqlite file database for CatalogContext
using ManningBooksApi;
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<CatalogContext>(options => #1
options.UseSqlite(
"DataSource=manningbooks.db;cache=shared")); #2
builder.Services.AddControllers();
builder.Services.AddSwaggerGen();
var app = builder.Build(); #3
using (var scope = app.Services.CreateScope()) #4
{
using (var dbContext = scope.ServiceProvider
.GetRequiredService<CatalogContext>()) #5
{
dbContext.Database.EnsureCreated(); #6
}
}
app.UseHttpsRedirection();
app.MapControllers();
app.UseSwagger();
app.UseSwaggerUI();
app.Run();
The registration supplies SQLite options, while a startup scope obtains a context to create the database. section 9.1



