ApplicationDbContext, DbContext and DbSet. What Purpose Do They each Serve?

Hi smart guys out there. Today, I will be writing on the trio of ApplicationDbContext, DbContext and DbSet. Also, you will be enlightened on the purpose they serve and their correct usage and in the end you will learn about Fluent Api.

  1. ApplicationDbContext

Definition:

  • A custom class in your application that inherits from the DbContext base class provided by Entity Framework Core.

  • It acts as the main gateway to interact with the database using EF Core.

Purpose:

  • Manages the database connection and entities in the application.

  • Contains DbSet properties for each entity, allowing LINQ queries and CRUD operations.

  • Configures entity relationships and behaviors through Fluent API or annotations.

Usage:

  • Typically registered in Startup.cs (in earlier .net core) or Program.cs for Dependency Injection (DI) like so:
services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

And in the custom class:

public class ApplicationDbContext : DbContext
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }

    public DbSet<User> Users { get; set; }
    public DbSet<Order> Orders { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // Custom entity configurations
    }
}

When building an API in a .NET Core application, it is indeed a common convention to create an ApplicationDbContext class that inherits from DbContext. This practice serves several important purposes which we will be looking at below. Viz:

1. Centralized Management of Database Access

  • The ApplicationDbContext acts as the bridge between your application and the database. It provides a single point of access to manage database connections, execute queries, and interact with your database using the Entity Framework Core (EF Core) ORM.

2. Encapsulation of Data Models

  • By defining DbSets (e.g., DbSet<User> Users) in the ApplicationDbContext, you encapsulate all the database entities in one place. This makes it easier to manage and maintain relationships between tables and entities.

3. Entity Configuration

  • The ApplicationDbContext is a convenient place to configure entity behavior using Fluent API or Data Annotations. For instance, you can set up table names, relationships, constraints, and indexes here.

4. Dependency Injection

  • By registering ApplicationDbContext in the Dependency Injection (DI) container (via services.AddDbContext<ApplicationDbContext>()), you can easily inject it into your services or controllers, promoting a decoupled and testable architecture.

5. Code-First Migrations

  • If you're using EF Core's Code-First approach, the ApplicationDbContext serves as the base for generating and applying database migrations. This ensures your database schema stays in sync with your application's data models.

6. Customizations and Extensions

  • The ApplicationDbContext can be extended to include custom functionality, like logging queries, overriding SaveChanges for auditing, or adding helper methods specific to your application.

7. Separation of Concerns

  • By isolating database interaction logic in the ApplicationDbContext, you maintain a clear separation between the data access layer and other parts of your application, following the principles of clean architecture.

2. DbContext

  • Definition:

    • A base class in EF Core that provides APIs to interact with the database.

    • Serves as a unit of work, tracking changes made to your entities and coordinating database transactions.

  • Features:

    • Tracks entities in memory (change tracking).

    • Manages database connections.

    • Allows overriding of methods for custom behavior (e.g., SaveChanges).

  • Commonly Used Methods:

    • SaveChanges: Commits changes to the database.

    • Add, Update, Remove: Perform basic CRUD operations.

    • Set<TEntity>: Dynamically access DbSets by type.

  • Example of Customization:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder.UseSqlServer("YourConnectionString");
}

Are you still following?

3. DbSet

  • Definition:

    • Represents a table or view in your database.

    • Each DbSet property in the DbContext corresponds to a collection of entities of a specific type. Say, you are to add these 2 entities User and Product.

  • Purpose:

    • Acts as a queryable source to perform LINQ queries.

    • Provides methods for adding, removing, and updating entities in the database.

  • Usage:

    • Defined as properties in the ApplicationDbContext class:
public DbSet<User> Users { get; set; }
public DbSet<Product> Products { get; set; }
  • Common Methods:

    • Add, AddRange: Add new entities.

    • Find: Retrieve an entity by its primary key.

    • Remove: Delete an entity.

  • Example Query:

var activeUsers = context.Users.Where(u => u.IsActive).ToList();

4. Fluent API

  • Definition:

    • A way to configure entity behavior in EF Core using the OnModelCreating method.

    • Provides more control than data annotations.

Example:

modelBuilder.Entity<User>()
    .HasIndex(u => u.Email)
    .IsUnique();

Final Note:

Why These Components Matter

  • ApplicationDbContext provides an application-specific implementation for interacting with the database.

  • DbContext is the foundation, offering core database management capabilities.

  • DbSet connects your code to specific database tables and allows manipulation through EF Core.

  • Together, they enable clean, testable, and maintainable database interactions using high-level abstractions.