liveBook · Manning

Code-first approach

As explained in .NET in Action, Second Edition

A code-first schema is a database schema generated from application entity definitions and ORM configuration.

A code-first approach starts with application entities rather than an existing database schema. Entity Framework Core (EF Core) uses those definitions and its configuration to generate tables; for a persistent database, it can generate migrations to create the schema. Database-first mapping starts with an existing schema instead. section 5.1

A minimal EF Core model has three parts:

  • An entity class defines the data to store. A Book with Id and Title maps to a Books table; EF Core treats Id as the primary key by convention. A different property can be marked with [Key]. section 5.2
  • A class derived from DbContext identifies the model. Its DbSet<Book> Books property includes Book in that model, while OnConfiguring selects a database provider. section 5.2
  • Application code adds entities, calls SaveChanges, and queries the DbSet. Do not use one DbContext concurrently across parallel tasks or threads. 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
}

The context listing connects the Book entity to a DbSet and configures an in-memory provider. That provider keeps the first application runnable without a separate database, but is intended only for development. section 5.2

Relationships can also begin in entity code. A Book collection of Ratings is recognized as one-to-many; EF Core gives Ratings a foreign key even without an explicit BookId property. Collections on both Book and Tag express a many-to-many relationship, for which EF Core creates a join table. Explicit foreign keys are possible, but these examples rely on conventions. section 5.2.3

Add ratings through an entity

Create a Book, add two Rating objects to its Ratings collection, add the Book to the context, and call SaveChanges. Query the book and use Include(b => b.Ratings) when printing its ratings. This exercises both the code-defined relationship and the saved data. section 5.2.3

Conventions are a starting point, not a guarantee of every database constraint. In the one-to-one example, database-level enforcement needs additional techniques such as a unique constraint on the foreign key; EF Core does not add those techniques for this code-first schema. section 5.2.3

How .NET in Action, Second Edition covers it

How deep it goes
Works through entities, a DbContext, saving, querying, and relationship conventions; does not work through migration commands.
Examples
Builds a book catalog with an in-memory database, then adds ratings and illustrates a many-to-many tag relationship.
What it assumes
Assumes basic C# class and property syntax while building EF Core setup from a new console application.
What you can do after
Build it from scratch with EF Core entities, a DbContext, and an in-memory provider, then save and query records.
How it connects
Connects DbContext, DbSet, primary keys, foreign keys, navigation properties, migrations, and database providers.

Also explained in

Compare how 4 books explain code-first approach →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of .NET in Action, Second Edition. The section links point to the parts of the book it draws on.