-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Empty instance instead of null returned for owned navigation property #23198
Comments
Note for triage: this repos on 5.0. It happens when there is an owned dependent that itself references two more owned dependents, but has no other nullable properties. So this: public class AnAggregateRoot
{
public string Id { get; set; }
public AnOwnedTypeWithOwnedProperties AnOwnedTypeWithOwnedProperties { get; set; }
}
public class AnOwnedTypeWithOwnedProperties
{
public AnOwnedTypeWithPrimitiveProperties1 AnOwnedTypeWithPrimitiveProperties1 { get; set; }
public AnOwnedTypeWithPrimitiveProperties2 AnOwnedTypeWithPrimitiveProperties2 { get; set; }
}
public class AnOwnedTypeWithPrimitiveProperties1
{
public string Name { get; set; }
}
public class AnOwnedTypeWithPrimitiveProperties2
{
public string Name { get; set; }
} Results in creating an {
"Id":"5c21da82-c3c2-4a63-9fa6-7250c9e0732d",
"AnEntity":null,
"AnOwnedTypeWithPrimitiveProperties":null,
"AnOwnedTypeWithPrimitiveAndOwnedProperties":null,
"AnOwnedTypeWithHasOneProperties":null,
"AnOwnedTypeWithOwnedProperties":
{
"AnOwnedTypeWithPrimitiveProperties1":null,
"AnOwnedTypeWithPrimitiveProperties2":null
}
} However, if we add a nullable property to public class AnOwnedTypeWithOwnedProperties
{
public string Name { get; set; }
public AnOwnedTypeWithPrimitiveProperties1 AnOwnedTypeWithPrimitiveProperties1 { get; set; }
public AnOwnedTypeWithPrimitiveProperties2 AnOwnedTypeWithPrimitiveProperties2 { get; set; }
} Then an instance of {
"Id":"3cde2228-0c82-4b30-a622-cd8f1d75f0e8",
"AnEntity":null,
"AnOwnedTypeWithPrimitiveProperties":null,
"AnOwnedTypeWithPrimitiveAndOwnedProperties":null,
"AnOwnedTypeWithHasOneProperties":null,
"AnOwnedTypeWithOwnedProperties":null
} |
Related #21488 |
As per decision made in #23564 , the intermediate owned entity which is optional dependent but has no properties in it (apart from PK shared with principal), will act as required dependent and we will always materialize the instance. i.e. we are preserving the behavior which is being shown here. This is required in case if the nested owned entity has a value then it would be materialized rather than getting lost if the intermediate just returned null. |
An optional dependent considered present If all non-nullable non-PK properties have a non-null value, or If all non-nullable non-PK properties are shared with principal then at least one nullable non shared property has a non-null value If there are no non-shared properties then it is always present and act like a required dependent Resolves #23564 Resolves #21488 Resolves #23198
An optional dependent considered present If all non-nullable non-PK properties have a non-null value, or If all non-nullable non-PK properties are shared with principal then at least one nullable non shared property has a non-null value If there are no non-shared properties then it is always present and act like a required dependent Resolves #23564 Resolves #21488 Resolves #23198
Another issue with fetching owned dependents: #24165 |
As per new decision, since materializing the intermediate owned entity is somewhat non-deterministic without looking at data for nested dependents, we are going to throw for this scenario. User can either configure the first owned relationship to be required dependent (so it will always be materialized) or add a required property in intermediate entity which can serve as discriminator to identify if the intermediate entity exist or not in database. |
So, if I understand the "solution" to this behavior (when you need the first owned property materialized to null), you should add a required "dummy" property/column that will tell EF if the entire object should be materialized to null or default? My situation is (example): The Person object will be materialized to default even when saved as null. Is this the expected behavior? |
When fetching an entity (owner) with a relationship (OwnsOne) to an optional owned type with null values I'm receiving in a certain case an empty instance with all properties null while I'm expecting the navigation property of the owned type itself to be null. According to issue 9005, the plan for .NET Core 3.0 is returning a null entity when all properties are null. This behavior works as expected when owning a type with simple properties or with foreign key relationships, but not when owning a type that owns other types (nested table splitting). I made a small demo to show the inconsistent behavior when fetching null values for a complex owned type that has relationships to other owned types in comparison with other cases that works as expected. In this demo example I conclude the following results when fetching empty navigation properties:
Console output
Like you can see in the json output only the owned type with owned properties case is returning an empty instance instead of null. I can't reproduce this behavior when using an in-memory database (all outcome are null as expected there) but I do have this issue when using the SqlServer database provider.
Is this a bug?
I really need the root navigation property to be null in all cases. Is there any workaround possible?
EF Core version: 3.1.9
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: .NET Core 3.1 and .NET 5.0
Operating system: Windows 1909
IDE: Visual Studio 2019 16.7.6
The text was updated successfully, but these errors were encountered: