簡體   English   中英

閱讀可能不存在的 Azure DocumentDB 文檔

[英]Read Azure DocumentDB document that might not exist

我可以像這樣從 Azure DocumentDB 查詢單個文檔:

var response = await client.ReadDocumentAsync( documentUri );

如果文檔不存在,這將拋出 DocumentClientException。 在我的程序中,我遇到了文檔可能存在也可能不存在的情況。 有沒有什么方法可以在不使用 try-catch 並且不需要兩次往返服務器的情況下查詢文檔,首先查詢文檔,然后檢索文檔是否存在?

遺憾的是,沒有其他方法,要么處理異常,要么進行 2 次調用,如果選擇第二條路徑,這里是一種性能驅動的檢查文檔存在的方法:

public bool ExistsDocument(string id)
{
    var client = new DocumentClient(DatabaseUri, DatabaseKey);
    var collectionUri = UriFactory.CreateDocumentCollectionUri("dbName", "collectioName");
    var query = client.CreateDocumentQuery<Microsoft.Azure.Documents.Document>(collectionUri, new FeedOptions() { MaxItemCount = 1 });
    return query.Where(x => x.Id == id).Select(x=>x.Id).AsEnumerable().Any(); //using Linq
}

客戶端應該在您所有的數據庫訪問方法之間共享,但我在那里創建了它以提供一個自動足夠的示例。

new FeedOptions () {MaxItemCount = 1}將確保查詢將針對 1 個結果進行優化(我們真的不需要更多)。

Select(x=>x.Id)將確保沒有其他數據被返回,如果你沒有指定它並且文檔存在,它將查詢並返回它的所有信息。

您專門查詢給定文檔,當ReadDocumentAsync找不到特定文檔(在狀態代碼中返回 404)時,它將拋出該DocumentClientException 在此處記錄 通過捕獲異常(並看到它是 404),您不需要兩次往返。

要解決此異常,您需要使用CreateDocumentQuery()進行查詢而不是離散讀取。 然后,您將獲得一個可以枚舉的結果集(即使該結果集為空)。 例如:

var collLink = UriFactory.CreateDocumentCollectionUri(databaseId, collectionId);
var querySpec = new SqlQuerySpec { <querytext> };

var itr = client.CreateDocumentQuery(collLink, querySpec).AsDocumentQuery();
var response = await itr.ExecuteNextAsync<Document>();

foreach (var doc in response.AsEnumerable())
{
    // ...
}

使用這種方法,您將不會得到任何回應。 在您的特定情況下,您將添加WHERE子句以通過其 id 查詢特定文檔,您將獲得零個結果或一個結果。

使用 CosmosDB SDK 版本。 3 有可能。 您可以檢查容器中是否存在項目並通過使用Container.ReadItemStreamAsync<T>(string id, PartitionKey key)並檢查response.StatusCode來獲取它:

using var response = await container.ReadItemStreamAsync(id, new PartitionKey(key));

if (response.StatusCode == HttpStatusCode.NotFound)
{
    return null;
}

if (!response.IsSuccessStatusCode)
{
    throw new Exception(response.ErrorMessage);
}

using var streamReader = new StreamReader(response.Content);

var content = await streamReader.ReadToEndAsync();

var item = JsonConvert.DeserializeObject(content, stateType);

然而,這種方法有一個缺點。 您需要手動反序列化該項目。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM