简体   繁体   中英

Cosmos DB: save object type as a property in document

I want to save object type as a part of json object when upsert my object into cosmos db. I've tried to pass a json serializer when instantiating instance of Cosmos Client, but it doesn't work. I still don't see type of object in document. What I was trying to do:

    public static readonly JsonSerializerSettings DefaultJsonSerializerSettings =
        new JsonSerializerSettings
        {
            TypeNameHandling = TypeNameHandling.All,
            DateFormatString = "o",
            DateFormatHandling = DateFormatHandling.IsoDateFormat,
        }; 

    var CosmosClient =
            new DocumentClient(
                new Uri(CosmosConfig.ServiceEndpoint),
                CosmosConfig.AuthNKey,
                DefaultJsonSerializerSettings,
                connectionPolicySettings);

Any other way to have such a behavior without preprocessing (converting object to jObject) first? Thanks

Upd:

What I trying to achive is smth like next structure in my document (automaticaly serialized type):

    {
      "$type" : "MyNamespace.Foo",
      "Id": "1560e1be-bf87-4720-a22e-b7e2c4c37f2e",
      "Name" : "Vasia"
    }

instead of current one like this (without type):

    {
      "Id": "1560e1be-bf87-4720-a22e-b7e2c4c37f2e",
      "Name" : "Vasia"
    }

When using Cosmos DB I often let my documents/classes inherit from an abstract base class similar to this:

public abstract class DocModel
{
    [JsonProperty(PropertyName = "$type")]
    public virtual string Doctype => GetType().Name;

    [JsonProperty(PropertyName = "id")]
    public string Id { get; set; }
}

which pretty much give you what you were looking for:

public class Cloud : DocModel
{
    public string Name { get; set; }
}

public class Foo : DocModel
{
    public string Name { get; set; }
}

Would end up as

{
   "$type":"Cloud",
   "id": "1560e1be-bf87-4720-a22e-b7e2c4c37f2e",
   "name" : "Vasia"
}

{
   "$type":"Foo",
   "id": "2560e1be-bf87-4720-a22e-b7e2c4c37f2e",
   "name" : "Vasia2"
}

You could change Doctype property to GetType().FullName etc. to get namespace and such.

This also allows you to query all documents based on Doctype, something like:

   var t = typeof(T).Name;
   IDocumentQuery<T> query = _db.Client
            .CreateDocumentQuery<T>(_db.CollectionUri, new FeedOptions { MaxItemCount = -1 })
            .Where(predicate)
            .Where(_ => _.Doctype == t)
            .AsDocumentQuery();

To be used in a generic repository for example.

According to my understanding you mean to say that you want to recognise the type of entity like Customer, Seller,etc.

If that is so I would like to inform you that Cosmos DB is schema less database and hence you cannot have it in format like Customer,etc. If you really need to recognize the type of object in Cosmos DB you will have to add one property like Type="Customer" or Type="Employee" in your object or entity which you want to save because all objects in DocumentDB are stored in similar form and that is JSON there is nothing concept like table of Customer/Employee as in SQL.

Dont forget to mark my answer if it helps you..

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM