【问题标题】:How to update document in Azure CosmosDB in C#如何在 C# 中更新 Azure CosmosDB 中的文档
【发布时间】:2018-01-31 17:33:10
【问题描述】:

我有一个从 Cosmos DB 加载文档的方法。文档不是强类型,也不能是强类型。我想更新文档上的各种属性,然后将该文档推送回 CosmosDB。

我遇到的问题是我要更新的属性嵌套在另一个对象下面,我找不到有关如何向下导航到该子属性并更新它的文档。

这是我目前正在尝试做的事情。

var project = await Service.GetById(projectId) as Microsoft.Azure.Documents.Document;

var gate = project.GetPropertyValue<dynamic>("IdeaInitiatedGate");
project.SetPropertyValue("IdeaInitiatedGate.VpApprovalStatus", status);
project.SetPropertyValue("IdeaInitiatedGate.VpApprovalComments", comments);
project.SetPropertyValue("IdeaInitiatedGate.VpApprovalOn", DateTime.Now);
project.SetPropertyValue("IdeaInitiatedGate.Status", status == "Approved" ? "Completed" : "Rejected");
if (status == "Approved")
{
    project.SetPropertyValue("CharterReview.Status", "Active");
}
var document = await Service.Replace(project);

Service 只是实际 CosmosDB 调用的包装器。上述代码发生的情况是,正在文档根目录下名为“IdeaInitiatedGate.VpApprovalStatus”的文档中创建新属性。我想要发生的是将 IdeaInitiatedGate 的 VpApprovalStatus 属性更新为新值。

想要更新这个

{
  "IdeaInitiatedGate": {
    "VpApprovalStatus": "Approved"
  }
}

不要创建这个

{
  "IdeaInitiatedGate.VpApprovalStatus": "Approved"
}

我最终得到的最终工作解决方案如下。基本上我使用 GetPropertyValue 来拉出我想要的动态根对象,然后我更改这个对象和整个动态对象的 SetProperty 值。

if (!(await Service.GetById(projectId) is Document project)) return null;

var gate = project.GetPropertyValue<dynamic>("IdeaInitiatedGate");
gate.VpApprovalStatus = status;
gate.VpApprovalComments = comments;
gate.VpApprovalOn = DateTime.Now;
gate.Status = status == "Approved" ? "Completed" : "Rejected";
project.SetPropertyValue("IdeaInitiatedGate", gate);

if (status == "Approved")
{
    var charterGate = project.GetPropertyValue<dynamic>("CharterReview");
    charterGate.Status = "Active";
    project.SetPropertyValue("CharterReview", charterGate);
}
var result = await Service.Replace(project);

【问题讨论】:

  • 如果gatedynamic 类型,那么你不能直接使用动态API:gate.VpApprovalStatus = "Approved" 吗?

标签: c# azure azure-cosmosdb


【解决方案1】:

我们可以用 JObject 设置 IdeaInitiatedGate 属性

project?.SetPropertyValue("IdeaInitiatedGate", new JObject { { "VpApprovalStatus", status }});

如果您想为 IdeaInitiatedGate 添加多个属性。我们可以通过以下方式来做。

project?.SetPropertyValue("IdeaInitiatedGate", new JObject { { "VpApprovalStatus", "Approved" },{ "VpApprovalComments", comments},{ "VpApprovalOn", DateTime.Now }});

以下是演示代码。它在我这边工作正常。

var project = (Document)client.CreateDocumentQuery<dynamic>(UriFactory.CreateDocumentCollectionUri(databaseName, collectionName))
            .AsEnumerable()
            .First();
var gate = project?.GetPropertyValue<dynamic>("IdeaInitiatedGate");
project?.SetPropertyValue("IdeaInitiatedGate", new JObject { { "VpApprovalStatus", "Approved" }});
var document = client.ReplaceDocumentAsync(UriFactory.CreateDocumentUri(databaseName, collectionName, project?.Id), project).Result.Resource;

从 Azure 门户检查:

【讨论】:

  • 问题是 IdeaInitiatedGate 实际上是一个具有许多属性的大对象,而不仅仅是我列出的那个,所以我不能只设置这几个属性,我需要设置所有东西,但我没有不知道所有属性是什么。我正在设置的那些可能已经或可能不存在于 Gate 对象中。
  • 我使用了你所说的基础知识,但改变了它。有关我最终做了什么的详细信息,请参阅问题。
猜你喜欢
  • 1970-01-01
  • 2022-10-07
  • 2018-09-29
  • 2019-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-09
  • 1970-01-01
相关资源
最近更新 更多