Required owned entity on a TPH derived type is materialized for an unrelated row
- Dominant language
- C#
- Stars
- 14.8k
- Forks
- 3.4k
- PR merge metrics
- PR metrics pending
Description
### Bug description
Using TPH, a derived type has a required `OwnsOne` navigation:
[efcore-tph-required-owned-repro.zip](https://github.com/user-attachments/files/30072042/efcore-tph-required-owned-repro.zip)
```csharp
modelBuilder.Entity(builder =>
{
builder.OwnsOne(x => x.Shape);
builder.Navigation(x => x.Shape).IsRequired();
});
```
The database contains only a `LineOverlay` and no `CircleOverlay` rows. However,
querying the base type still invokes the `Circle` constructor with `null`:
```csharp
await db.Overlays.AsNoTracking().ToListAsync();
```
```text
CircleOverlay rows in database: 0
Circle constructor called: point is null = True, radius = 0
System.ArgumentNullException: Value cannot be null. (Parameter 'point')
```
## Expected
EF materializes the `LineOverlay` without invoking the `Circle` constructor,
because the row discriminator is `LineOverlay`.
## Reproduction
Run the attached project:
```shell
dotnet run
```
Reproduced with:
- EF Core / SQLite provider 10.0.10
- .NET 10.0
This appears related to #31353, which was fixed in 8.0.3. Unlike that issue,
this owned navigation is explicitly configured as required. Making it optional
avoids the exception, but changes the model semantics: every `CircleOverlay`
must have a `Circle`.
### Your code
```csharp
A complete minimal runnable reproduction project is attached:
[EfCoreTphRequiredOwnedRepro.zip](replace-with-the-link-generated-by-GitHub)
Run it with:
dotnet run
```
### Stack traces
```text
Materializing the base TPH query...
Circle constructor called: point is null = True, radius = 0
Unhandled exception. System.ArgumentNullException: Value cannot be null. (Parameter 'point')
at System.ArgumentNullException.Throw(String paramName)
at System.ArgumentNullException.ThrowIfNull(Object argument, String paramName)
at Circle..ctor(String point, Double radius) in C:\myfiles\mytemp\projects\efcore-tph-required-owned-repro\Program.cs:line 62
at lambda_method84(Closure, QueryContext, DbDataReader, ResultContext, SingleQueryResultCoordinator)
at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
at Program.$(String[] args) in C:\myfiles\mytemp\projects\efcore-tph-required-owned-repro\Program.cs:line 32
```
### Verbose output
```text
```
### EF Core version
10.0.10
### Database provider
Microsoft.EntityFrameworkCore.Sqlite
### Target framework
.NET 10
### Operating system
_No response_
### IDE
_No response_
Contributor guide
Assessment
This issue has not been assessed yet.