dotnet / dotnet/efcore

Support optional owned type with a required nested owned type

Open
#37,260 3 comments 0 reactions 0 assignees View on GitHub
area-owned-entities area-query customer-reported
Dominant language
C#
Stars
14.8k
Forks
3.4k
PR merge metrics
PR metrics pending

Description

### Question

I'm building a booking system, and EF Core keeps rejecting my configuration with following error:
```
Entity type '[EntityType]' is an optional dependent using table sharing and containing other dependents without any required non shared property to identify whether the entity exists. If all nullable properties contain a null value in database then an object instance won't be created in the query causing nested dependent's values to be lost. Add a required property to create instances with null values for other properties or mark the incoming navigation as required to always create an instance....
```
I want to understand exactly why this is invalid, even though it seems like a natural domain model.

### **Domain Scenario**
A **HotelRoom** may or may not have a **BasePrice** (some rooms aren’t priced yet during setup).

If BasePrice *does* exist:

- It always has a required **RegularPrice**
- It may have a **SeasonalDiscount**
- SeasonalDiscount, when present, always has:
- a required **DiscountPrice**
- a required **DiscountPeriod**

So the conceptual structure is:
```
Room
└── BasePrice (optional)
├── RegularPrice (required)
└── SeasonalDiscount (optional)
├── DiscountPrice (required)
└── DiscountPeriod (required)
```
This matches the business logic perfectly.

```
builder.OwnsOne(r => r.BasePrice, basePrice =>
{
// Required regular price
basePrice.OwnsOne(p => p.RegularPrice, regular =>
{
regular.Property(p => p.Amount).IsRequired();

regular.OwnsOne(p => p.Currency, currency =>
{
currency.Property(c => c.Code).IsRequired();
});
});
basePrice.Navigation(p => p.RegularPrice).IsRequired();

// Optional discount
basePrice.OwnsOne(p => p.SeasonalDiscount, discount =>
{
// Required nested dependents
discount.OwnsOne(d => d.DiscountPrice, dp =>
{
dp.Property(p => p.Amount).IsRequired();
});
discount.Navigation(d => d.DiscountPrice).IsRequired();

discount.OwnsOne(d => d.DiscountPeriod, period =>
{
period.Property(p => p.Start).IsRequired();
period.Property(p => p.End).IsRequired();
});
discount.Navigation(d => d.DiscountPeriod).IsRequired();
});

basePrice.Navigation(p => p.SeasonalDiscount).IsRequired(false);
});

// BasePrice itself is optional on Room
builder.Navigation(r => r.BasePrice).IsRequired(false);
```

### **❓ My Question**

Why does EF Core forbid this shape?

Specifically:
- **Why does EF Core not allow required owned types (DiscountPrice and DiscountPeriod) to exist under an optional owned type (BasePrice → SeasonalDiscount → required children)?**
- Is this limitation fundamental to how EF Core materializes owned entities?
- Is this considered “by design” or a limitation in EF Core?
- Are there recommended patterns for modeling business scenarios where:
- A parent component may be optional
- But its internal components, when present, are non-optional?

I want to understand the **core rule** and **the reasoning behind it**, not just how to work around it.

_**Thank you — any detailed insight is appreciated.**_

### EF Core version

8.0.11

### Database provider

Npgsql.EntityFrameworkCore.PostgreSQL

### Target framework

.NET 8

### Operating system

macOS Tahoe 26.1

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.