Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 可以在嵌套属性上使用Document.SetPropertyValue(字符串,字符串)吗?_.net_Azure Cosmosdb - Fatal编程技术网

.net 可以在嵌套属性上使用Document.SetPropertyValue(字符串,字符串)吗?

.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,我会使用什么语法?以下内容似乎不像我预

对于给定的DocumentDb文档,例如:

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