Fluent API when configuring your db context. In Azure Cosmos, the RAW json is exposed in the "__json" property. This can be read using Newtonsoft library and you can add properties that are unmapped and read them afterwards. You should not only save the changes to persist them in Azure Cosmos but also re-read the data again to get an updated item in your container (table) in Azure Cosmos DB. The following extension methods allows to write and read such unmapped properties easier using Azure Cosmos DB.
public static class AzureCosmosEntityExtensions
{
public static TResult? GetUnmappedProperty<TResult, T>(this T entity, string propname, DbContext context) where T : class {
if (entity == null)
{
return default(TResult);
}
var entry = context.Entry(entity);
var rawJson = entry.Property<JObject>("__jObject");
var currentValueProp = rawJson.CurrentValue[propname];
if (currentValueProp == null)
{
return default(TResult);
}
var currentValuePropCasted = currentValueProp.ToObject<TResult?>();
return currentValuePropCasted;
}
public static void SetUnmappedProperty<T>(this T entity, string propname, object value, DbContext context) where T : class
{
if (entity == null)
{
return;
}
var entry = context.Entry(entity);
var rawJson = entry.Property<JObject>("__jObject");
rawJson.CurrentValue[propname] = JToken.FromObject(value);
entry.State = EntityState.Modified;
}
}
Let's see some sample code to set this up. Consider the following model :
public class Address
{
public string AddressId { get; set; }
public string State { get; set; }
public string City { get; set; }
public string Street { get; set; }
public string HouseNumber { get; set; }
}
Let's add another unmapped property "LastUpdate" that are not exposed in the domain model, but is an unmapped model. We must as mentioned make sure to reload the data we read here after saving
the entity to test out reading the unmapped property. Note that we set ModelState to Modified to trigger the saving of these unmapped properties, since the ChangeTracker is not
tracking them and EF will not save the updates to these unmapped properties if this is not done.
//Create a db context and for an item entity in a container (table) in Azure Cosmos DB,
//set the unmapped property to a value and also read out this property after saving it and reloading the entity
using var context = await contextFactory.CreateDbContextAsync();
var address = await context.Addresses.FirstAsync();
const string unmappedPropKey = "LastUpdate";
address.SetUnmappedProperty(unmappedPropKey, DateTime.UtcNow, context);
await context.SaveChangesAsync();
address = await context.Addresses.FirstAsync();
var unnmappedProp = address.GetUnmappedProperty<DateTime, Address>(unmappedPropKey, context);
The following screenshot below shows the unmapped property LastUpdate was written to Azure Cosmos DB item in the container (table).