Tutorials Entity Framework Core Mastery

Owned Entity Types (Value Objects)

On this page

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."

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