dotnet / efcore

EF Core is a modern object-database mapper for .NET. It supports LINQ queries, change tracking, updates, and schema migrations.
https://docs.microsoft.com/ef/
MIT License
13.68k stars 3.16k forks source link

Cosmos: allow excluding null values from Json document #26981

Open aligunel opened 2 years ago

aligunel commented 2 years ago

When using

[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
  [JsonPropertyName("age")]
  public int? Age { get; set; }

This still will create null when saving data in Cosmos Db

{
"age" : null
}

or is there anyway to prevent this ? This issue tracker is for documentation

For product issues, use https://github.com/aspnet/EntityFramework/issues

ajcvickers commented 2 years ago

@aligunel JsonIgnore is an attribute used by the JSon serializer; it does not change the EF model. NotMapped can be used to exclude a property from the EF model.

aligunel commented 2 years ago

@aligunel JsonIgnore is an attribute used by the JSon serializer; it does not change the EF model. NotMapped can be used to exclude a property from the EF model.

Problem is I want "age" in the cosmos db document if value only exists. [Notmapped] attribute will ignore it even there is a data for the field.

ajcvickers commented 2 years ago

@aligunel I don't think that is supported.

aligunel commented 2 years ago

I think EF COre 6 for Cosmos db is very immature. No support for JsonSerialization options. I need to define ToJsonProperty() for each property. It is not easy to integrate to existing cosmos db.

AndriySvyryd commented 1 week ago

Consider moving HasDefaultValue to Core. When querying it would be used for missing values and for null values if the property is not nullable. If not set then above scenarios should throw.

Consider adding SaveWhenNotDefault to PropertySaveBehavior. This won't send the value to the database if it's same as the specified default (or the CLR default if HasDefaultValue wasn't called). When specified for AfterSaveBehavior it will try to remove the value instead of updating to the default value when mapped to JSON.

roji commented 1 week ago

To continue @AndriySvyryd's comment above, we should carefully consider the interaction of this client-side default mechanism with the existing "sentinel value" mechanism we already have, which is about detecting when the user has set a property and when they haven't (e.g. for not sending a property to the database to allow it to get generated there).

Keep in mind that relational also has JSON mapping, where all of the same considerations apply as for non-relational JSON document databases.

/cc @damieng