EF Core Relationships
Learn how to model one-to-many and many-to-many relationships between entities in Entity Framework Core.
One-to-Many Relationships
EF Core infers relationships from your entity classes by convention — a foreign key property and a navigation property are usually all you need.
public class Project{ public int Id { get; set; } public string Name { get; set; } = ""; public List<TaskItem> Tasks { get; set; } = new(); // one Project has many Tasks}
public class TaskItem{ public int Id { get; set; } public string Title { get; set; } = "";
public int ProjectId { get; set; } // foreign key public Project? Project { get; set; } // navigation property}Loading Related Data
By default, EF Core doesn't load related data automatically — you opt in with `Include`, which prevents accidentally fetching far more data than a query actually needs.
List<Project> projects = await context.Projects .Include(p => p.Tasks) .ToListAsync();
foreach (var project in projects){ Console.WriteLine($"{project.Name}: {project.Tasks.Count} tasks");}Many-to-Many Relationships
Modern EF Core can configure many-to-many relationships directly, without you needing to define the join table entity yourself.
public class TaskItem{ public int Id { get; set; } public string Title { get; set; } = ""; public List<Tag> Tags { get; set; } = new();}
public class Tag{ public int Id { get; set; } public string Name { get; set; } = ""; public List<TaskItem> Tasks { get; set; } = new();}// EF Core automatically creates a hidden join table for thisFAQs
The navigation property will simply be empty/null rather than throwing an error — a common source of confusing bugs, so it's worth checking for whenever related data seems to be missing.
Summary
- EF Core infers relationships from foreign keys and navigation properties.
- Include() explicitly loads related data — it isn't loaded automatically.
- Modern EF Core configures many-to-many relationships without a manual join entity.