Skip to content

EF Core Owned Entity — Complete Guide

DodaTech Updated 2026-06-24 3 min read

In this tutorial, you'll learn about EF Core Owned Entity. We cover key concepts, practical examples, and best practices.

Your Order has a shipping address with Street, City, ZipCode. You create a separate Address table with a foreign key, or you flatten all address fields into the Orders table. Owned entities map value objects as columns in the parent table without a separate table.

Wrong

public class Order
{
    public int Id { get; set; }
    public string ShippingStreet { get; set; }  // Flat columns
    public string ShippingCity { get; set; }
    public string ShippingZip { get; set; }
}

Output: Works. But Address is not reusable. The relationship is implicit.

Or a separate table:

public class Address
{
    public int Id { get; set; }
    public string Street { get; set; }
    // One-to-one with Order — separate table, foreign key
}

Output: Separate table and join for a value that is always loaded with the order.

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

public class Order
{
    public int Id { get; set; }
    public Address ShippingAddress { get; set; } // Owned entity
}

// Configuration
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Order>().OwnsOne(o => o.ShippingAddress);
}

Output: Orders table has ShippingAddress_Street, ShippingAddress_City, ShippingAddress_ZipCode columns. No separate table, no join. The Address class is reusable.

Prevention

  • Use OwnsOne for owned entities that are part of the parent (one-to-one in same table).
  • Use OwnsMany for collections of value objects (e.g., multiple phone numbers on a contact).
  • Use WithOwner for navigation from owned to owner: entity.OwnsOne(o => o.Address).WithOwner(a => a.Order).
  • Use owned entities for value objects from Domain-Driven Design.
  • Use [Owned] attribute instead of Fluent API for simple cases.
  • Use computed columns for owned entity properties if needed.

Common Mistakes with core owned entity

  1. Overlapping type class instances that cause GHC to reject the program with ambiguous dispatch errors
  2. Non-exhaustive pattern matches that compile with warnings then crash at runtime
  3. Misunderstanding that String is [Char] with poor performance for large text operations

These mistakes appear frequently in real-world EF code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.

Practice Exercise

Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.

This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.

FAQ

What is the difference between owned entity and complex type?

In EF Core, owned entities are the replacement for complex types from EF6. EF Core 8+ also introduced ComplexType() for truly value-typed semantics. Owned entities support tracking and can be null; complex types are immutable value objects.

Can an owned entity be shared across multiple owners?

No. An owned entity instance belongs to exactly one owner. If you need shareable entities (e.g., a Category referenced by many products), use a regular entity with a foreign key relationship instead.

How do I configure column names for owned entity properties?

Use the OwnsOne builder: modelBuilder.Entity<Order>().OwnsOne(o => o.ShippingAddress, a => { a.Property(p => p.Street).HasColumnName("ShipStreet"); });. Each property can be configured within the owned entity builder.

Owned entities are used in DodaTech's order processing for address, payment info, and shipping details. For more EF Core, visit DodaTech.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro