public class Product{
public int Id { get; set; }
public string Name { get; set; }
}
Then EF creates a table like:
- Id
- Name
Products
- Define models (classes)
- Use migrations to create/update DB
- EF syncs code → database
- Full control in code
- Version control friendly (migrations)
- Great for new projects
- Clean and flexible
- Requires migration management
- Not ideal for complex existing DBs
- Create tables in DB (SQL Server, etc.)
- Scaffold models using EF
- Existing DB → generate models
- EF reads schema and creates classes
- Best for existing/legacy databases
- DB controlled by DBAs
- No need to design schema in code
- Harder to maintain changes
- Regenerating models can overwrite changes
- Less control compared to Code First
| Feature | Code First | Database First |
|---|---|---|
| Starting point | C# classes | Database |
| Control | Developer (code) | Database |
| Schema updates | Migrations | DB changes + re-scaffold |
| Best for | New projects | Existing databases |
| Flexibility | High | Moderate |
- Building a new application
- Agile development (frequent changes)
- You want everything in code
- Working with existing DB
- DB already designed/managed
- Large enterprise systems
- Code First = Write blueprint → build house
- Database First = House exists → create blueprint
Modern development (especially with Entity Framework Core):
- Mostly prefers Code First + Migrations
- But Database First is still very useful for real-world legacy systems
When you modify your C# models (add property, remove property, new class, etc.), you don’t directly update the database.
Instead, you use Migrations.
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
// NEW FIELD
public decimal Price { get; set; }
}
Add-Migration AddPriceToProduct
EF generates a migration file like:
migrationBuilder.AddColumn<decimal>(
name: "Price",
table: "Products",
nullable: false,
defaultValue: 0m);
Update-Database
This applies changes to DB.
EF migrations are incremental, not destructive (unless you explicitly make them so).
- Existing data stays
-
New column gets:
- Default value OR
- NULL (if nullable)
public decimal? Price { get; set; } // nullable → safe
- Must provide default value OR migration will fail
public decimal Price { get; set; } // requires default
EF might:
- Drop old column ❌
- Create new column ❌
👉 This can cause data loss unless handled manually.
✔ Fix:
migrationBuilder.RenameColumn(
name: "OldName",
table: "Products",
newName: "NewName");Note: Using rename retain the column data
- Column is dropped → data lost
public class Category
{
public int Id { get; set; }
public string Name { get; set; }
}
👉 Migration will:
- Create new table
- Existing tables/data remain unchanged
EF uses a special table:
👉 __EFMigrationsHistory
- Tracks applied migrations
- Ensures only new changes are applied
Never manually change DB in Code First workflow
public string? NewColumn { get; set; }
Then later enforce required
Check for:
- Drops ❌
- Renames ❌
- Data loss risks
Prevents data loss
Always before running:
Update-Database
Change Model → Add-Migration → Review Migration → Update-Database
- EF does NOT overwrite DB
- It applies incremental schema changes
- Existing data is safe unless you explicitly break it