Entity Framework Core Mastery

Owned Entity Types (Value Objects)

1 Views Updated 5/4/2026

Owned Entity Types (Value Objects)

In Domain-Driven Design (DDD), a Value Object is an object that has no identity of its own (no Primary Key) and is entirely defined by its properties. A classic example is a StreetAddress. If you and I have the exact same address string, we live in the same house. EF Core supports Value Objects via Owned Entities.

1. Modeling the Value Object

First, we create the C# class for the Address. Notice it has NO Id property.

public class Address
{
    public string Street { get; private set; }
    public string City { get; private set; }
    public string ZipCode { get; private set; }

    public Address(string street, string city, string zipCode)
    {
        Street = street;
        City = city;
        ZipCode = zipCode;
    }
}

2. Applying It to the Parent Entity

We use this Address type directly inside our User class.

public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    
    // The complex Value Object. It is fundamentally Owned by the User.
    public Address HomeAddress { get; set; } 
}

3. Table Splitting (The Fluent API Magic)

If we try to run a Migration now, EF Core will panic because it doesn't know how to map Address. We must use the OwnsOne() configuration.

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<User>(entity => 
    {
        // Tell EF Core that Address is completely dependent on User
        entity.OwnsOne(u => u.HomeAddress, addressMap => 
        {
            // By default, EF Core "Table Splits". It physically flattens the Address 
            // properties into the main 'Users' SQL table!
            addressMap.Property(a => a.Street).HasColumnName("Home_Street");
            addressMap.Property(a => a.City).HasColumnName("Home_City");
        });
    });
}
The Output: SQL Server generates ONE table named Users containing: [Id], [Name], [Home_Street], [Home_City].
When LINQ queries the row, EF Core automatically extracts those SQL columns and hydrates them into the nested C# Address object!

4. Interview Mastery

Q: "Why should we use an Owned Entity (Table Splitting) to store an Address, rather than just serializing the Address object to JSON and saving it in an NVARCHAR column?"

Architect Answer: "Queryability and Indexing. If you serialize the Address into a JSON string, SQL Server loses native relational awareness of those fields (unless you utilize specific SQL JSON syntax and computed columns). If you try to run `_context.Users.Where(u => u.HomeAddress.City == 'Chicago')`, a JSON string mapping will crash EF Core's LINQ translator. However, because Owned Entities utilize Table Splitting, the `City` physically exists as a standard `NVARCHAR` column in the `Users` table! That means you can write standard EF Core LINQ queries against the nested object properties, and you can even apply high-performance SQL B-Tree Indexes directly onto the `Home_City` column."

Entity Framework Core Mastery
1. Foundations & Architecture
Introduction to Object Relational Mapping (ORM) Entity Framework Core Architecture & Providers Setup and DbContext Integration Code-First vs Database-First Approaches Reverse Engineering Existing Databases (Scaffolding)
2. Code-First Modeling
Entity Conventions & Data Annotations The Fluent API Deep Dive (OnModelCreating) Primary Keys, Composite Keys, & Guids Required Properties & Database Defaults Value Conversions (Enums & Strongly Typed IDs)
3. Relational Architecture
One-to-Many Relationships & Foreign Keys One-to-One Relationships (Dependent Entities) Many-to-Many Relationships & Navigation Properties Owned Entity Types (Value Objects) Table-per-Hierarchy (TPH) Inheritance
4. Data Querying & LINQ
Basic LINQ Queries & IQueryable Execution Tracking vs No-Tracking Queries (Performance) Eager Loading vs Explicit Loading (Include) Lazy Loading Pitfalls & Proxies Client vs Server Evaluation Parsing
5. Manipulating Data (CUD)
Adding, Updating, and Removing Entities The ChangeTracker and Entity States Disconnected Entities in Web APIs Batch Updates and Deletes (.NET 7+)
6. Advanced Performance & Scale
Concurrency Tokens and Optimistic Locking Raw SQL Queries and Views (FromSqlRaw) Compiled Queries for High Throughput Interceptors (Logging & Auditing Data Changes) DbContext Pooling Mechanisms Managing Complex EF Core Migrations (CI/CD)