Reputation: 131
I use CosmosDb with the Entity Framework. I need that when saving data if one of the properties is null
, it is stored as undefined
.
Is there any option to initialize DbContext
from CosmosClient
, or set CosmosSerializationOptions
?
I tried the following option, but it does not work for me:
context.Database.GetCosmosClient().ClientOptions.SerializerOptions = new CosmosSerializationOptions()
{
IgnoreNullValues = true
};
The option without using EF is working:
CosmosClient cosmosClient = new CosmosClientBuilder(EndpointUri, PrimaryKey)
.WithSerializerOptions(new CosmosSerializationOptions() { IgnoreNullValues = true })
.Build();
//The current result
{
"Id": "fad8b443-6d10-4009-853c-efb6aac18031",
"Discriminator": "User",
"FirstName": "Charley",
"LastName": null
}
//Expected result
{
"Id": "fad8b443-6d10-4009-853c-efb6aac18031",
"Discriminator": "User",
"FirstName": "Charley"
}
Upvotes: 3
Views: 3728
Reputation: 61
I'm not using Entity Framework in my code, but in searching for the right way to get Cosmos to ignore null values, I found an alternative solution that may work for you.
I was inspired by the answer to this question to add a JsonProperty
attribute with ItemNullValueHandling
set to NullValueHandling.Ignore
for the classes I'm saving, like so:
[JsonObject(ItemNullValueHandling = NullValueHandling.Ignore)]
public class Foo
{
[JsonProperty(PropertyName="id")]
public string Id {get; set;}
[JsonProperty(PropertyName = "bar")]
public string Bar { get; set; }
[JsonProperty(PropertyName = "baz")]
public string Baz { get; set; }
}
async void Main()
{
Foo f = new Foo() { Id = "1", Bar = "bar" };
string azureSqlCoreApiPrimaryKey = "[REDACTED]";
string azureSqlCoreApiUrl = "[REDACTED]";
string cosmosDbName = "[REDACTED]";
string cosmosContainerName = "test";
CosmosClient cosmosClient = new CosmosClient(azureSqlCoreApiUrl, azureSqlCoreApiPrimaryKey);
var cosmosDb = cosmosClient.GetDatabase(cosmosDbName);
var cosmosContainer = cosmosDb.GetContainer(cosmosContainerName);
await cosmosContainer.CreateItemAsync(f);
}
In my tests, the document would have a null 'baz' attribute if and only if I commented out the JsonObject
property.
The accepted answer to that question suggests that you modify the options on a JsonSerializer
object instead of touching each class you're trying to save. This is analogous to how you tried to modify the serialization options on your CosmosClient
, but were ultimately unable to do so. I ended up moving to modifying the CosmosClient
serialization options myself, as you demonstrated. But in a case where you can't modify the serialization options, but you can modify the class you're writing, this is a possible workaround.
Upvotes: 5
Reputation: 15991
I've tried the sample and I found it really has no option to set IgnoreNullValues
when initialize the client, and here's the description:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder.UseCosmos(
"https://xxx.documents.azure.com:443/",
"primary key",
databaseName: "Tasks",
options => {
options.SerializerOptions(....);//there's no property choice to set
});
According to this situation, what you can do is modify the entity, such as removing the null property, and I found a similar question in st, I think you can refer to it. And if your entity always exists null value in some specific property(e.g one property 'userConf' may be a null property, you can create another entity without this property), you can even create another entity to meet your requirement.
Upvotes: 1