Courses/C#/EF Core Mastery
    Back to Course

    Lesson 34: EF Core Relationships, Tracking & Migrations Mastery

    Master one-to-many, many-to-many, and one-to-one relationships, plus database migrations for schema evolution.

    What You'll Learn

    • • One-to-Many, Many-to-Many, and One-to-One relationships
    • • Fluent API configuration and navigation properties
    • • Migrations workflow: create, apply, revert, and remove
    • • Advanced queries: filtered includes, ThenInclude, and raw SQL

    🧠 Real-World Analogy

    Relationships in EF Core mirror real life: an Author has many Books (one-to-many), a Book has many Tags and a Tag applies to many Books (many-to-many), and an Author has one Profile (one-to-one). Migrations are like version control for your database — each migration is a commit that can be applied or reverted.

    Entity Relationships

    EF Core supports three relationship types. Define them with navigation properties and configure them with Fluent API in OnModelCreating. EF Core 5+ supports skip navigations for many-to-many — no explicit join table needed.

    RelationshipExampleConfiguration
    One-to-ManyAuthor → BooksHasOne/WithMany + FK
    Many-to-ManyBook ↔ TagsHasMany/WithMany (auto join)
    One-to-OneAuthor → ProfileHasOne/WithOne + FK

    Entity Relationships & Fluent API

    Configure one-to-many, many-to-many, and one-to-one with Fluent API.

    Try it Yourself »
    C#
    using System;
    using System.Collections.Generic;
    using Microsoft.EntityFrameworkCore;
    
    // === One-to-Many ===
    public class Author
    {
        public int Id { get; set; }
        public string Name { get; set; } = "";
        public List<Book> Books { get; set; } = new();  // Navigation
    }
    
    public class Book
    {
        public int Id { get; set; }
        public string Title { get; set; } = "";
        public int AuthorId { get; set; }          // Foreign key
        public Author Author { get; set; } = null!; // Navigation
        
    
    ...

    Migrations

    Migrations are versioned SQL scripts generated from your model changes. They have Up() (apply) and Down() (revert) methods. In production, apply migrations at startup or via CI/CD — never use EnsureCreated() in production.

    Migrations Workflow

    Create, apply, and revert database migrations with the EF CLI.

    Try it Yourself »
    C#
    // === EF Core Migrations Workflow ===
    // Migrations track database schema changes over time
    
    // 1. Create initial migration
    // dotnet ef migrations add InitialCreate
    
    // Generated migration file:
    using Microsoft.EntityFrameworkCore.Migrations;
    
    public partial class InitialCreate : Migration
    {
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.CreateTable(
                name: "Authors",
                columns: table => new
                {
                    Id
    ...

    Advanced Queries

    Use ThenInclude for multi-level eager loading, filtered includes for conditional loading, and fall back to raw SQL when LINQ can't express your query efficiently.

    Multi-Level Include & Filtered Queries

    Load nested relationships and use filtered includes for targeted data loading.

    Try it Yourself »
    C#
    using System;
    using System.Linq;
    using Microsoft.EntityFrameworkCore;
    
    class Program
    {
        static void Main()
        {
            using var db = new LibraryContext();
            db.Database.EnsureCreated();
            
            // Seed data
            if (!db.Authors.Any())
            {
                var tag1 = new Tag { Name = "Fiction" };
                var tag2 = new Tag { Name = "Science" };
                var tag3 = new Tag { Name = "Classic" };
                
                db.Authors.AddRange(
                    new Author
    ...

    Pro Tip

    Use db.Database.Migrate() in Program.cs to auto-apply pending migrations at startup. For production, consider generating SQL scripts with dotnet ef migrations script and applying them through your CI/CD pipeline.

    Common Mistakes

    • • Using EnsureCreated() with migrations — they're mutually exclusive
    • • Deleting migration files manually — use dotnet ef migrations remove
    • • Cascade deleting unintentionally — always specify OnDelete behavior

    Lesson Complete!

    You've mastered EF Core relationships and migrations. Next, implement the Repository Pattern and Unit of Work for clean architecture.

    Sign up for free to track which lessons you've completed and get learning reminders.

    Previous

    Cookie & Privacy Settings

    We use cookies to improve your experience, analyze traffic, and show personalized ads. You can manage your preferences below.

    By clicking "Accept All", you consent to our use of cookies for analytics and personalized advertising. You can customize your preferences or reject non-essential cookies.

    Privacy PolicyTerms of Service