0

I have a parent class

public class Items{
    public Type FeedType { get; set; }
    public double Rating { get; set; }
}

I have two subclasses of this Items

public class SingleItemResponse : Items
{
    public string Id { get; set; }
}
public class MultipletemResponse : Items
{
    public IEnumerable<string> Ids { get; set; }
}

I have added a list of SingleItemResponses and MultipleItemResponses to the List of Items.

var list = new List<ItemResponse>();
list.add(single); // assume that single is a object of singleItemResponse
list.add(multiple); // assume that multiple is a object of multipleitem 

I can return the list with all the attributes of singleItemResponse and multipleItemResponse. However, I would like to store and retrieve them in documentDB. The problem is when I try to store them in DocumentDB as IList, they don't keep the values from Single and MultipleFeedItems, in this case it is an ID or Ids.

I would like to know how can I save and retrieve them, the only solution I have right now is to add them together in that ItemResponse but I would like to know if there is a better way without stuffing things.

Chit Khine
  • 830
  • 1
  • 13
  • 34
  • You mean storing `list` which contains single and multiple items in _one_ DocumentDB entry or two items to _two_ entries in DocDB separately? If my answer does not point to your problem, please write a comment to me. – Youngjae Oct 12 '16 at 05:32
  • @Youngjae the first one, the list which contains single and multiple items but i can only set the type to base type – Chit Khine Oct 13 '16 at 07:11
  • // I editted answer. Check it out. – Youngjae Oct 13 '16 at 15:16

1 Answers1

0

Method 1. Persist json hierarchy

In case of retrieving, if two derivated objects have distinguishable properties like Id and Ids, you can compare it in JObject first and then create to your types.

string collectionName = "YourCollectionName";
Guid id = Guid.Parse("275319a3-d395-46f2-9370-f3eadf691e03"); // Manually set GUID for test purpose.

Uri documentUri = UriFactory.CreateDocumentUri(DocumentDbDatabaseNameConfig, collectionName, id.ToString());
Uri collectionUri = UriFactory.CreateDocumentCollectionUri(DocumentDbDatabaseNameConfig, collectionName);

// test variables.
var list = new List<Items>();
list.Add(new SingleItemResponse() { Rating = 2.2d, Id = "id" });
list.Add(new MultipletemResponse() { Rating = 2.2d, Ids = new List<string>() { "ids1", "ids2"}});

JObject jInput = new JObject();
jInput.Add("id", id);
jInput.Add("list", JArray.FromObject(list));

// Store data.
var upsertedResult = _documentDbclient.UpsertDocumentAsync(collectionUri, jInput, null, true).Result;

// Read stored data.
var result = _documentDbclient.ReadDocumentAsync(documentUri).Result;

JObject jResult = (dynamic)result.Resource;

JArray jArray = (JArray) jResult["list"];
foreach (var jElement in jArray)
{
    if (jElement["Id"] != null)
    {
        SingleItemResponse single = (SingleItemResponse)jElement.ToObject(typeof(SingleItemResponse));
        // Do your job with single instance.
    }
    else if (jElement["Ids"] != null)
    {
        MultipletemResponse multiple = (MultipletemResponse)jElement.ToObject(typeof(MultipletemResponse));
        // Do your job with multiple instance.
    }
}

In addition, inserted data is as below;

{
  "id": "275319a3-d395-46f2-9370-f3eadf691e03",
  "list": [
    {
      "Id": "id",
      "Rating": 2.2
    },
    {
      "Ids": [
        "ids1",
        "ids2"
      ],
      "Rating": 2.2
    }
  ],
  "_rid": "KywuAN7aNQABAAAAAAAAAA==",
  "_self": "dbs/KywuAA==/colls/KywuAN7aNQA=/docs/KywuAN7aNQABAAAAAAAAAA==/",
  "_etag": "\"0000ee05-0000-0000-0000-57ff9ecb0000\"",
  "_attachments": "attachments/",
  "_ts": 1476370121
}

Method 2. Crunch into inline json serialized string

This method got a hint from this post. In my experience, I cannot make correct serialized result that contains its own type in each items. But in theory, it could work.

JObject jInput = new JObject();

// Use custom serialize/deserialize setting.
JsonSerializerSettings settings = new JsonSerializerSettings
{
    TypeNameHandling = TypeNameHandling.Auto
};

JArray jArray = JArray.FromObject(list);
string strJson = JsonConvert.SerializeObject(jArray, settings);

jInput.Add("id", id);
jInput.Add("strJson", strJson); // treat json just like strings.

var upsertedResult = _documentDbclient.UpsertDocumentAsync(collectionUri, jInput, null, true).Result;

var result = _documentDbclient.ReadDocumentAsync(documentUri).Result;
JObject jResult = (dynamic)result.Resource;
jResult.ToString().Dump();

List<Items> obj = JsonConvert.DeserializeObject<List<Items>>(jResult["strJson"].Value<string>(), settings);
Community
  • 1
  • 1
Youngjae
  • 24,352
  • 18
  • 113
  • 198