Demystifying the Code First approach in EF Core

Take advantage of the Code First approach in Entity Framework Core to create the data model for your application based on its domain entities in ASP.NET Core.

man holding code sign programmer developer devops data scientist tech roles hitesh choudhary via un
Hitesh Choudhary (CC0)

When we build database-backed enterprise applications, we generally want to isolate our entity models, the DbContext, and the logic for database initialization and migration to maintain a clean architecture. We can do this by taking advantage of the Code First approach in Entity Framework Core.

This article presents a discussion of the Code First approach in EF Core with code examples to illustrate the concepts. To use the code examples provided in this article, you should have Visual Studio 2022 installed in your system. If you don’t already have a copy, you can download Visual Studio 2022 here.

Create an ASP.NET Core Web API project in Visual Studio

To create an ASP.NET Core Web API project in Visual Studio 2022, follow the steps outlined below.

  1. Launch the Visual Studio 2022 IDE.
  2. Click on “Create new project.”
  3. In the “Create new project” window, select “ASP.NET Core Web API” from the list of templates displayed.
  4. Click Next.
  5. In the “Configure your new project” window, specify the name and location for the new project.
  6. Optionally check the “Place solution and project in the same directory” check box, depending on your preferences.
  7. Click Next.
  8. In the “Additional Information” window shown next, select “.NET 8.0 (Long Term Support)” as the framework version and ensure that the “Use controllers” box is checked. We won’t be using minimal APIs in this project.
  9. Elsewhere in the “Additional Information” window, leave “Authentication Type” set to “None” (the default) and make sure the check boxes “Enable Open API Support,” “Configure for HTTPS,” and “Enable Docker” remain unchecked. We won’t be using any of those features here.
  10. Click Create.

We’ll use this ASP.NET Core Web API project to work with EF Core and the Code First approach in the sections below.

Creating an entity model in EF Core

Microsoft’s EF Core is an object-database mapper that simplifies data access for .NET Core applications. EF Core works with relational databases, non-relational databases, and even in-memory databases, and allows us to write code to perform CRUD (create, read, update, delete) operations that use .NET objects. By using EF Core, we don’t have to interact directly with the underlying database provider.

EF Core supports three different approaches to create the entity model: Code First, Model First, and Database First.

The Code First approach in EF Core

In the Code First approach, the entity model is defined using code without any pre-existing database schema. Developers write domain classes and configure the mapping between those classes and the database using attributes, fluent APIs, or conventions. EF Core then creates the database schema based on the code-defined model. The Code First approach allows you to express complex relationships using code. It is often preferred when the database schema is unavailable.

The Model First approach in EF Core

In the Model First approach, the entity model is designed using a visual design tool, such as the Entity Framework Designer in Visual Studio. With the designer, developers can visually create entities, relationships, and other aspects of a data model without writing a single line of code. Once you’ve defined the model, EF Core generates the code, including the entity classes and the mapping configurations. You can later extend the code to add business logic or customizations as appropriate. Model First can be beneficial when non-developers are involved in defining the data model or when an existing database schema needs to be reverse-engineered.

The Database First approach in EF Core

In the Database First approach, an existing database schema is used to generate the entity model using EF Core tools. These tools can generate entity classes and mapping configurations by reverse engineering the database schema. It is also possible to synchronize database schema changes with the entity model. When developers use the Database First approach, they gain more control over the database structure but less control over the code model. This approach is a good choice when integrating EF Core with an existing database or working with legacy databases.

Using the Code First approach in EF Core

Before you can use EF Core in your application, you must add the Microsoft.EntityFrameworkCore package to your project. To do this, select the project in the Solution Explorer window, then right-click and select “Manage NuGet Packages.” In the NuGet Package Manager window, search for the Microsoft.EntityFrameworkCore package and install it.

Alternatively, you can install the package via the NuGet Package Manager console by entering the command below.

PM> Install-Package Microsoft.EntityFrameworkCore

With that out of the way, let’s now create a data model using the Code First approach in EF Core. We’ll do this in five steps: Define the domain classes, create the DbContext class, configure the DbContext, register the DbContext, and finally migrate the database.

Step 1: Define your domain classes

Start by creating the domain classes that correspond to the entities in your application. The following code snippet defines an Author class and its members.

public class Author
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Address { get; set; }
}

Step 2: Create the DbContext class

Create a class that extends the DbContext class of EF Core. This class represents your database context and is the gateway to all communications between your application and the database. In other words, the DbContext class acts as the entry point for performing CRUD operations on the data.

public class AuthorDbContext : DbContext
{
    public DbSet<Author> Authors { get; set; }
    public AuthorDbContext(DbContextOptions<AuthorDbContext> options)
        : base(options)
    {
    }
}

Note how the DbContextOptions instance is passed to the constructor of this class. This instance will contain the database provider and connection string information your application needs to connect to the database.

Step 3: Configure the DbContext

Next override the OnModelCreating method of your AuthorDbContext class to configure the model and its relationships as shown in the code snippet below.

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Author>()
        .Property(p => p.FirstName).IsRequired().HasMaxLength(50);
}

Step 4: Register the DbContext

Now register the AuthorDbContext with the dependency injection container using the following code snippet. This will allow your application to access the DbContext instance throughout its life cycle.

builder.Services.AddDbContext<AuthorDbContext>(options =>     
options.UseSqlServer(Configuration.GetConnectionString("AuthorDb")));

Step 5: Migrate the database

In this final step we take advantage of the migration feature of EF Core to create or update the database schema based on our data model. To do this, run the following command at the EF Core CLI window or the NuGet Package Manager console.

dotnet ef migrations add InitialMigration

And that’s all you have to do to get your application up and running using the Code First approach.

Each of the three approaches to creating a data model in EF Core has its pros and cons. You should select the right approach for your application depending on the requirements. I’ll discuss the other two approaches, Model First and Database First, in detail in future posts here.

Copyright © 2024 IDG Communications, Inc.