8 minlesson

Entity Relationships in EF Core

Entity Relationships in EF Core

Real-world data is rarely isolated. Customers place orders, authors write blog posts, and students enroll in courses. EF Core lets you model these connections between entities so that your C# object graph mirrors the actual relationships in your database.

Why Relationships Matter

Without relationships, you would store everything in flat, disconnected tables and manually join data with raw SQL. EF Core relationships give you:

  • Object navigation: Access related data through properties like blog.Posts instead of writing JOIN queries
  • Automatic foreign keys: EF Core creates and manages FK columns for you
  • Cascade operations: Deleting a parent can automatically delete its children
  • Query integration: Use LINQ to filter and include related data in a single query
csharp
1// Without relationships - manual join
2var posts = await context.Posts
3 .Where(p => p.BlogId == blogId)
4 .ToListAsync();
5
6// With relationships - navigation property
7var blog = await context.Blogs
8 .Include(b => b.Posts)
9 .FirstOrDefaultAsync(b => b.Id == blogId);
10
11// Now blog.Posts contains all related posts

Types of Relationships

EF Core supports three fundamental relationship types that map directly to relational database concepts:

One-to-Many (1:N)

The most common relationship. One entity is associated with many instances of another entity.

1┌──────────┐ ┌──────────┐
2│ Blog │ 1───* │ Post │
3│ │ │ │
4│ Id │ │ Id │
5│ Name │ │ Title │
6│ │ │ BlogId │ ← Foreign key
7└──────────┘ └──────────┘

Examples: A blog has many posts. A department has many employees. A customer has many orders.

One-to-One (1:1)

Each entity is associated with at most one instance of the other entity.

1┌──────────┐ ┌─────────────┐
2│ User │ 1───1 │ UserProfile │
3│ │ │ │
4│ Id │ │ Id │
5│ Email │ │ Bio │
6│ │ │ UserId │ ← Foreign key
7└──────────┘ └─────────────┘

Examples: A user has one profile. An order has one shipping address. A country has one capital city.

Many-to-Many (N:M)

Each entity can be associated with multiple instances of the other entity.

1┌──────────┐ ┌───────────┐ ┌──────────┐
2│ Student │ *───* │ Enrolled │ *───* │ Course │
3│ │ │ (join) │ │ │
4│ Id │ │ StudentId │ │ Id │
5│ Name │ │ CourseId │ │ Title │
6└──────────┘ └───────────┘ └──────────┘

Examples: Students enroll in many courses, and each course has many students. Posts can have many tags, and each tag applies to many posts.

Navigation Properties

Navigation properties are the C# mechanism for traversing relationships. They come in two forms:

Reference Navigation

Points to a single related entity. Used on the "many" side of a one-to-many or either side of a one-to-one relationship.

csharp
1public class Post
2{
3 public int Id { get; set; }
4 public string Title { get; set; } = string.Empty;
5
6 // Reference navigation to the parent Blog
7 public Blog Blog { get; set; } = null!;
8}

Collection Navigation

Points to a collection of related entities. Used on the "one" side of a one-to-many relationship.

csharp
1public class Blog
2{
3 public int Id { get; set; }
4 public string Name { get; set; } = string.Empty;
5
6 // Collection navigation to child Posts
7 public ICollection<Post> Posts { get; set; } = new List<Post>();
8}

Foreign Key Properties

A foreign key property stores the ID of the related entity. EF Core can infer foreign keys by convention, but you can also declare them explicitly for clarity:

csharp
1public class Post
2{
3 public int Id { get; set; }
4 public string Title { get; set; } = string.Empty;
5
6 public int BlogId { get; set; } // Foreign key property
7 public Blog Blog { get; set; } = null!; // Navigation property
8}

Declaring the FK property gives you direct access to the related entity's ID without loading the full entity.

How EF Core Discovers Relationships

EF Core uses conventions to detect relationships automatically:

  1. Navigation property detected - EF Core sees Blog property on Post
  2. Inverse navigation matched - It pairs Post.Blog with Blog.Posts
  3. Foreign key inferred - It looks for a property named BlogId or BlogFK
  4. Relationship configured - One-to-many from Blog to Post via BlogId

When conventions are not sufficient, you can use the Fluent API in OnModelCreating to configure relationships explicitly. We will cover each configuration approach in the following presentations.

Summary

In this lesson, you learned:

  • Relationships connect entities and enable navigation between related data
  • EF Core supports one-to-many, one-to-one, and many-to-many relationships
  • Navigation properties (reference and collection) let you traverse relationships in C#
  • Foreign key properties store the related entity's ID in the database
  • EF Core discovers most relationships automatically through conventions

Next, we will dive deep into each relationship type, starting with one-to-many.