.net 可以在嵌套属性上使用Document.SetPropertyValue(字符串,字符串)吗?
对于给定的DocumentDb文档,例如:.net 可以在嵌套属性上使用Document.SetPropertyValue(字符串,字符串)吗?,.net,azure-cosmosdb,.net,Azure Cosmosdb,对于给定的DocumentDb文档,例如: { "id": "CDC101", "title": "Fundamentals of database design", "authordetails": { "Name" : "Dave", "Age : "33" }, "credits": 10 } 如果我想使用SetPropertyValue更新authordetails.Name,我会使用什么语法?以下内容似乎不像我预
{
"id": "CDC101",
"title": "Fundamentals of database design",
"authordetails": {
"Name" : "Dave",
"Age : "33"
},
"credits": 10
}
如果我想使用SetPropertyValue更新authordetails.Name,我会使用什么语法?以下内容似乎不像我预期的那样有效:
//Fetch the Document to be updated
Document doc = client.CreateDocumentQuery<Document>(collectionLink)
.Where(r => r.Id == "CDC101")
.AsEnumerable()
.SingleOrDefault();
//Update some properties on the found resource
doc.SetPropertyValue("authordetails.Name", "Mike");
//Now persist these changes to the database by replacing the original resource
Document updated = await client.ReplaceDocumentAsync(doc);
//获取要更新的文档
Document doc=client.CreateDocumentQuery(collectionLink)
.其中(r=>r.Id==“CDC101”)
.可计算的()
.SingleOrDefault();
//更新找到的资源的某些属性
文档SetPropertyValue(“authordetails.Name”、“Mike”);
//现在,通过替换原始资源将这些更改持久化到数据库中
文档更新=等待客户端.ReplaceDocumentAsync(文档);
我问这个问题的原因是:我必须更改集合中大量文档的单个属性(新要求),我正试图从单独进程的队列中处理它们,以避免UI超时。我考虑过一个存储过程,但是基于javascript,没有像mongo这样的批量升级,我无法找到一个合适的、可伸缩的方法来实现这一点。我不熟悉NoSQL的思维方式,对此我感到困惑。非常感谢您的帮助。SetPropertyValue不支持设置嵌套属性。您可以在提交此用户语音。目前,我们可以将文档作为对象进行查询,然后替换文档。请参阅以下代码:
var entity = client.CreateDocumentQuery<Cred>(UriFactory.CreateDocumentCollectionUri("<databaseid>", "<collectionid>")).Where(r => r.ID == "CDC101")
.AsEnumerable().SingleOrDefault();
entity.AuthInfo.Name = "mike";
await client.ReplaceDocumentAsync(UriFactory.CreateDocumentUri("<databaseid>", "<collectionid>", entity.ID), entity);
我们也可以使用商店产品来实现这一点:
// SAMPLE STORED PROCEDURE
function sample() {
var collection = getContext().getCollection();
// Query documents and take 1st item.
var isAccepted = collection.queryDocuments(
collection.getSelfLink(),
'SELECT * FROM root r',
function (err, feed, options) {
if (err) throw err;
// Check the feed and if empty, set the body to 'no docs found',
// else take 1st element from feed
if (!feed || !feed.length) getContext().getResponse().setBody('no docs found');
else getContext().getResponse().setBody(JSON.stringify(feed[0]));
var doc= feed[0];
doc.authordetails.Name="mike";
var isAccepted = collection.replaceDocument(feed[0]._self, doc);
});
if (!isAccepted) throw new Error('The query was not accepted by the server.');
}
这种方法对我有效:
可以使用GetPropertyValue以动态方式读写嵌套属性
//Fetch the Document to be updated
Document doc = client.CreateDocumentQuery<Document>(collectionLink)
.Where(r => r.Id == "CDC101")
.AsEnumerable()
.SingleOrDefault();
dynamic AuthInfo = doc.GetPropertyValue<dynamic>("AuthInfo");
AuthInfo.Name = "mike";
doc.SetPropertyValue("AuthInfo", AuthInfo);
//Now persist these changes to the database by replacing the original resource
Document updated = await client.ReplaceDocumentAsync(doc);
//获取要更新的文档
Document doc=client.CreateDocumentQuery(collectionLink)
.其中(r=>r.Id==“CDC101”)
.可计算的()
.SingleOrDefault();
动态AuthInfo=doc.GetPropertyValue(“AuthInfo”);
AuthInfo.Name=“mike”;
doc.SetPropertyValue(“AuthInfo”,AuthInfo);
//现在,通过替换原始资源将这些更改持久化到数据库中
文档更新=等待客户端.ReplaceDocumentAsync(文档);
谢谢您的回答,但我如何能够通过字符串路径而不是代码动态更新属性,即:理想情况下:doc.fields[“authordetails.Name”]=“mike”;而不是:doc.authordetails.Name=“mike”;我想我需要搜索必填字段。据我所知,目前不可能。我建议您通过我在此答案中提供的链接提交一个语音。在堆栈溢出答案中通常会用到一些解释性的词语。很抱歉,我以前从未在堆栈溢出中编写过,并且在格式化文本时遇到了一些问题。解释:Azure.Document类的IdynamicMetadataProvider实现已损坏(或者不管叫什么名字,)因此,它不知道如何为嵌套属性设置属性。但是,您可以将其顶级属性设置为属性。但是,它的所有嵌套属性都是像JObject、JArray这样的Newtonsoft类型,它们有自己的、未中断的IDynamicMetadataProvider接口实现。因此,一旦剥离顶级对象(示例中的AuthInfo是JObject),您可以操作它,然后在完成后在根Azure.Document上设置该对象。
//Fetch the Document to be updated
Document doc = client.CreateDocumentQuery<Document>(collectionLink)
.Where(r => r.Id == "CDC101")
.AsEnumerable()
.SingleOrDefault();
dynamic AuthInfo = doc.GetPropertyValue<dynamic>("AuthInfo");
AuthInfo.Name = "mike";
doc.SetPropertyValue("AuthInfo", AuthInfo);
//Now persist these changes to the database by replacing the original resource
Document updated = await client.ReplaceDocumentAsync(doc);