Code First vs Database First in ASP.
NET Core
API with Entity Framework Core
This guide explains the difference between the Code First and Database First approaches in [Link] Core APIs
using Entity Framework Core. It covers both design-time and runtime behavior with practical examples.
Feature Code First Database First
Starting Point C# Classes Existing Database
Database Creation Generated using migrations Already exists
Source of Truth Code Database
Best For New Projects Legacy/Enterprise Systems
Schema Changes Handled via migrations Handled in database
Developer Workflow Code -> Database Database -> Code
1. Code First Approach
In the Code First approach, developers create C# entity classes first. Entity Framework Core uses those classes to
generate the database schema.
Design-Time Flow
1. Create model classes.
2. Create DbContext.
3. Add migrations.
4. Update the database.
Flow:
C# Classes → EF Core → Migration → SQL Server Database
Example Model Class
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
DbContext Example
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions<AppDbContext> options)
: base(options)
{
}
public DbSet<Student> Students { get; set; }
}
Migration Commands
dotnet ef migrations add InitialCreate
dotnet ef database update
Runtime Behavior
// Querying data at runtime
var students = await [Link]();
// EF Core converts it to:
SELECT * FROM Students
2. Database First Approach
In the Database First approach, the database already exists. EF Core generates model classes and DbContext from
the database schema.
Design-Time Flow
1. Create database tables manually.
2. Use Scaffold-DbContext.
3. EF Core generates classes.
Flow:
SQL Database → Scaffold → C# Classes
SQL Table Example
CREATE TABLE Students(
Id INT PRIMARY KEY IDENTITY,
Name NVARCHAR(100),
Age INT
);
Scaffold Command
dotnet ef dbcontext scaffold
"Server=.;Database=SchoolDB;Trusted_Connection=True;"
[Link]
Generated Model Example
public partial class Student
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
Runtime Behavior
var students = [Link]();
// EF Core generates:
SELECT * FROM Students
3. Complete [Link] Core API Example (Code First)
[Link] Configuration
[Link]<AppDbContext>(options =>
[Link](
[Link]("DefaultConnection")));
StudentsController Example
[ApiController]
[Route("api/[controller]")]
public class StudentsController : ControllerBase
{
private readonly AppDbContext _context;
public StudentsController(AppDbContext context)
{
_context = context;
}
[HttpGet]
public async Task<IActionResult> Get()
{
var students = await _context.[Link]();
return Ok(students);
}
[HttpPost]
public async Task<IActionResult> Create(Student student)
{
_context.[Link](student);
await _context.SaveChangesAsync();
return Ok(student);
}
}
4. Real-World Recommendation
Most modern [Link] Core API projects use the Code First approach because: Database migrations are easier to
manage. Schema changes are version controlled with Git. CI/CD pipelines become simpler. Refactoring is easier.
Database First is usually preferred in: Legacy enterprise applications DBA-controlled systems Large existing
databases Projects with heavy stored procedure usage
One-Line Summary
Code First: Database is generated from code.
Database First: Code is generated from database.