【问题标题】:[DocumentDB .NET SDK]What is the difference between ReadDocumentAsync and CreateDocumentQuery when replacing[DocumentDB .NET SDK]替换时ReadDocumentAsync和CreateDocumentQuery有什么区别
【发布时间】:2018-01-26 06:39:28
【问题描述】:

请先看代码。

在第 8 步中,该字段未更新。 在步骤 11&12 中,该字段被更新。

我有 2 个问题。

ReadDocumentAsync 和 CreateDocumentQuery 替换时有什么区别?

用DocumentQuery得到的值进行替换是否合适?


控制台应用程序

NuGet 包(Microsoft.Azure.DocumentDB 1.19.1,Newtonsoft.Json 9.0.1)


using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Client;
using Microsoft.Azure.Documents.Linq;
using Newtonsoft.Json;
using System;
using System.Collections.ObjectModel;
using System.Configuration;
using System.Linq;

class Program
{
    static string endpoint = ConfigurationManager.AppSettings["endpoint"];
    static string key = ConfigurationManager.AppSettings["key"];
    static string database = ConfigurationManager.AppSettings["database"];
    static string collection = ConfigurationManager.AppSettings["collection"];
    static void Main(string[] args)
    {
        ConnectionPolicy cp = new ConnectionPolicy()
        {
            ConnectionMode = ConnectionMode.Direct,
            ConnectionProtocol = Protocol.Https,
            RetryOptions = new RetryOptions()
            {
                MaxRetryAttemptsOnThrottledRequests = 5,
                MaxRetryWaitTimeInSeconds = 60,
            }
        };

        var client = new DocumentClient(new Uri(endpoint), key, cp);
        //Step1 Create Database
        client.CreateDatabaseIfNotExistsAsync(new Database { Id = database }).Wait();

        //Step2 Create Collection(400RU)
        client.CreateDocumentCollectionIfNotExistsAsync(UriFactory.CreateDatabaseUri(database),
            new DocumentCollection
            {
                Id = collection,
                PartitionKey = new PartitionKeyDefinition()
                { Paths = new Collection<string>() { "/partitionKey" } }
            }
            , new RequestOptions { OfferThroughput = 400 }).Wait();

        //Step3 Insert TestData
        var id1 = Guid.NewGuid().ToString();
        client.CreateDocumentAsync(UriFactory.CreateDocumentCollectionUri(database, collection)
            , new TestDocument() { TestField = "initialvalue", PartitionKey = "default", Id = id1, }).Wait();
        var id2 = Guid.NewGuid().ToString();
        client.CreateDocumentAsync(UriFactory.CreateDocumentCollectionUri(database, collection)
            , new TestDocument() { TestField = "initialvalue", PartitionKey = "default", Id = id2, }).Wait();

        //Step4 ID1 GetDocument(ReadDocument)
        var readDocument = client.ReadDocumentAsync<TestDocument>(UriFactory.CreateDocumentUri(database, collection, id1),
            new RequestOptions() { PartitionKey = new PartitionKey("default") }).Result.Document;

        //Step5 ID2 GetDocument(DocumentQuery)
        var queryDocument = client.CreateDocumentQuery<TestDocument>(UriFactory.CreateDocumentCollectionUri(database, collection),
            new FeedOptions { MaxItemCount = 1, EnableCrossPartitionQuery = false, })
            .Where(x => x.PartitionKey == "default" && x.Id == id2)
            .AsDocumentQuery().ExecuteNextAsync<TestDocument>().Result.FirstOrDefault();

        //Step6 ChangeValue
        readDocument.TestField = "newvalue";
        queryDocument.TestField = "newvalue";

        //Step7 ID1 Replace
        var updateResult1 = client.ReplaceDocumentAsync(UriFactory.CreateDocumentUri(database, collection, readDocument.Id), readDocument).Result;
        //Step8 ID2 Replace
        var updateResult2 = client.ReplaceDocumentAsync(UriFactory.CreateDocumentUri(database, collection, queryDocument.Id), queryDocument).Result;

        //Step9 ID1 select
        var id1Updated = client.ReadDocumentAsync<TestDocument>(UriFactory.CreateDocumentUri(database, collection, id1),
            new RequestOptions() { PartitionKey = new PartitionKey("default") }).Result.Document;
        //Step10 ID2 select
        var id2Updated = client.ReadDocumentAsync<TestDocument>(UriFactory.CreateDocumentUri(database, collection, id2),
            new RequestOptions() { PartitionKey = new PartitionKey("default") }).Result.Document;

        Console.WriteLine(id1Updated.TestField); //newvalue
        Console.WriteLine(id2Updated.TestField); //initialvalue
        Console.ReadLine();

        //Step11 ID2 SetPropertyValue
        queryDocument.SetPropertyValue("testField", "newvalue2");
        //Step12 ID2 Replace
        var updateResultX = client.ReplaceDocumentAsync(UriFactory.CreateDocumentUri(database, collection, queryDocument.Id), queryDocument).Result;
        //Step13 ID2 select
        var id2UpdatedX = client.ReadDocumentAsync<TestDocument>(UriFactory.CreateDocumentUri(database, collection, id2),
            new RequestOptions() { PartitionKey = new PartitionKey("default") }).Result.Document;
        Console.WriteLine(id2UpdatedX.TestField); //newvalue2
        Console.ReadLine();
    }
}
public class TestDocument : Document
{
    [JsonProperty("partitionKey")]
    public string PartitionKey { get; set; }
    [JsonProperty("testField")]
    public string TestField { get; set; }
}

【问题讨论】:

  • 嗨,现在有更新吗?我的回答对你有帮助吗?
  • 在 [queryDocument.TestField = "newvalue";] 之前添加 [queryDocument = (dynamic) queryDocument;] 后,我得到了预期的行为。为什么会这样?
  • 嗨,sak_o。我会检查你提供的主题并发表我的想法。

标签: .net azure azure-cosmosdb


【解决方案1】:

ReadDocumentAsync 和 ReadDocumentAsync 有什么区别 替换时是否创建文档查询?

您应该在查询中使用ReadDocumentAsync 进行简单的 ID 查找。

在服务器端,ReadDocumentAsync(REST API 上的 GET)在吞吐量 (RU) 和延迟方面更轻量级。没有 SQL 解析/编译/索引扫描,只是直接查找。

ReadDocumentAsync 将在找不到特定文档时抛出 DocumentClientException(在状态码中返回 404),这在 here 中提到。

要解决此异常,您可以先使用CreateDocumentQuery() 进行查询而不是直接读取。然后,您将简单地获得一个结果集。

将 DocumentQuery 获得的值用于 替换?

是的,您可以使用 DocumentQuery 获得的文档进行替换操作。请参考以下代码的sn-p:

private async Task updateDoc()
{
    string EndpointUri = "xxxxx";
    string PrimaryKey = "xxxxx";
    DocumentClient client;

    client = new DocumentClient(new Uri(EndpointUri), PrimaryKey);

    Document doc = client.CreateDocumentQuery<Document>(UriFactory.CreateDocumentCollectionUri("db", "coll"))
                .Where(r => r.Id == "**")
                .AsEnumerable()
                .SingleOrDefault();

    MyMode mode= (dynamic)doc;

    mode.name = "updated value";

    //replace document
    Document updateddoc = await client.ReplaceDocumentAsync(doc.SelfLink, mode);


    Console.WriteLine(updateddoc);
}

public class MyMode
{
    public string id { get; set; }
    public string name { get; set; }
}

希望对你有帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-23
    • 1970-01-01
    • 2019-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-13
    相关资源
    最近更新 更多