Understanding Why ThenInclude() Fails with ToList() in EF Core

Entity Framework Core (EF Core) simplifies loading related entities using Include() and ThenInclude(). However, developers frequently encounter a puzzling bug: eager loading works fine during direct foreach iteration, but appending .ToList() causes nested navigation properties to materialize as null.

The Root Cause: Identity Resolution and Misconfigured Relationships

When you iterate over an IQueryable directly in a loop, EF Core streams results row by row. However, calling .ToList() materializes all entities into memory at once and triggers EF Core's relationship fixup mechanism via the Change Tracker.

If there is a slight misconfiguration in your OnModelCreating mapping (specifically around 1-to-1 relationships and foreign keys), the Change Tracker fails during relationship fixup when processing the entire list, resulting in null navigation properties.

Solution 1: Fix the Fluent API Mapping

When mapping a 1-to-1 relationship, ensure you explicitly define the foreign key on the dependent entity. Ambiguous mappings lead to change tracker conflicts during list materialization: