【问题标题】:How to store a data from child class in DocumentDB?如何在 DocumentDB 中存储子类的数据?
【发布时间】:2016-10-12 04:23:18
【问题描述】:

我有一个父类

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

我有这个 Items 的两个子类

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

我已将 SingleItemResponses 和 MultipleItemResponses 列表添加到项目列表中。

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 

我可以返回具有 singleItemResponse 和 multipleItemResponse 的所有属性的列表。但是,我想在 documentDB 中存储和检索它们。问题是当我尝试将它们作为 IList 存储在 DocumentDB 中时,它们不会保留 Single 和 MultipleFeedItems 的值,在这种情况下它是一个 ID 或 Id。

我想知道如何保存和检索它们,我现在唯一的解决方案是将它们添加到 ItemResponse 中,但我想知道是否有更好的方法而不需要填充东西。

【问题讨论】:

  • 您的意思是将包含单个和多个项目的list 存储在一个 DocumentDB 条目中,还是将两个项目分别存储到两个 条目中?如果我的回答没有指向您的问题,请给我写评论。
  • @Youngjae 第一个,包含单个和多个项目的列表,但我只能将类型设置为基本类型
  • // 我编辑了答案。看看吧。

标签: c# crud azure-cosmosdb


【解决方案1】:

方法一、保持json层次结构

在检索的情况下,如果两个派生对象具有IdIds等可区分的属性,您可以先在JObject中进行比较,然后再根据您的类型创建。

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.
    }
}

另外,插入的数据如下;

{
  "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
}

方法2. 压缩成内联json序列化字符串

这个方法得到了this post的提示。以我的经验,我无法制作正确的序列化结果,其中每个项目都包含自己的类型。但理论上,它可以工作。

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);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-04
    • 2017-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-09
    • 1970-01-01
    相关资源
    最近更新 更多