Tutorials Entity Framework Core Mastery

One-to-One Relationships (Dependent Entities)

On this page

One-to-One Relationships (Dependent Entities)

Unlike One-to-Many, a One-to-One relationship is strict mapping. A User can only have exactly one IdentityPassport. These are typically used to split a massive "God Table" with 150 columns into smaller, manageable tables for performance reasons (Vertical Partitioning).

1. Modeling the C# Classes

Because the relationship is 1:1, there are NO collections (List<T>) involved. Both sides hold a single reference to the other.

public class User // The Principal (The entity that can exist on its own)
{
    public int Id { get; set; }
    public string Name { get; set; }

    // Reference Navigation
    public IdentityPassport Passport { get; set; } 
}

public class IdentityPassport // The Dependent (Cannot exist without a User)
{
    public int Id { get; set; }
    public string PassportNumber { get; set; }

    // Navigation and Foreign Key to the parent
    public int UserId { get; set; }
    public User User { get; set; }
}

2. Applying the Fluent API Configuration

Setting up 1:1 relationships natively via EF Conventions is highly prone to erratic errors because EF Core struggles to figure out which table is the "Parent" and which table is the "Child." We must explicitly tell the Fluent API who holds the Foreign Key.

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<User>(entity =>
    {
        // Read out loud: "A user HAS ONE Passport...
        entity.HasOne(u => u.Passport)
              // WITH ONE User attached back to the Passport...
              .WithOne(p => p.User)
              // And the IdentityPassport table is the one that possesses the Foreign Key column!
              .HasForeignKey<IdentityPassport>(p => p.UserId);
    });
}
The Generic Tag Requirement: Notice the <IdentityPassport> generic marker attached to the HasForeignKey method. In a 1:1 relationship, either table COULD theoretically hold the foreign key. You MUST tell the system which side gets the SQL column.

3. Primary Key as Foreign Key (The Elegant Hack)

Because it's a 1:1 relationship, a separate UserId column feels redundant. The Passport's own Primary Key can just be the User's ID. If the User is ID #5, the Passport is forced to be ID #5.

public class SecureVault 
{
    // Both the Primary Key AND the Foreign Key simultaneously!
    public int UserId { get; set; } 
    public User User { get; set; }
}

// Fluent API configuration
modelBuilder.Entity<User>()
            .HasOne(u => u.SecureVault)
            .WithOne(s => s.User)
            .HasForeignKey<SecureVault>(s => s.UserId);

modelBuilder.Entity<SecureVault>().HasKey(s => s.UserId);

4. Interview Mastery

Q: "Why would we ever split a User's columns (e.g., BloodType, PassportImage) into a separate 1:1 Table instead of just keeping them as nullable columns on the primary User table?"

Architect Answer: "The decision revolves around SQL Server's 8KB Page limits and network I/O optimization. If the `User` table contains massive byte[] array columns for passport images and biometric data, standard LINQ queries (`Select * from Users`) will drag extreme amounts of data across the network even when the UI just wants to display a username. By 'Vertically Partitioning' the heavy unstructured data into a separate 1:1 table (`IdentityPassport`), the main `User` table stays incredibly lightweight, narrow, and fits densely into CPU Caches. We explicitly `.Include(u => u.Passport)` ONLY when the UI specifically requires the heavy biometric data."

Questions on this lesson 0

Sign in to ask a question or upvote helpful answers.

No questions yet — be the first to ask!

Entity Framework Core Mastery
Course syllabus
1. Foundations & Architecture
2. Code-First Modeling
3. Relational Architecture
4. Data Querying & LINQ
5. Manipulating Data (CUD)
6. Advanced Performance & Scale
Toolliyo Assistant
Ask about tutorials, ebooks, training, pricing, mentor services, and support. I use public site content only—not admin or internal tools.

care@toolliyo.com

Need callback? Share your details