練習 - 讀取和查詢項目
回想一下,您的應用程式預期都會將項目新增至 Azure Cosmos DB for NoSQL 容器,並將這些項目讀回驗證。 此時,您的應用程式已成功將項目新增至容器。 有兩種讀取項目的主要方式:執行點讀取,或執行查詢。
目前有三個主要需求:
- 使用唯一識別碼和資料分割索引鍵值來點讀取項目
- 使用簡單的查詢字串建立查詢
- 使用摘要反覆運算器分頁查詢的結果
完成此練習之後,您的應用程式即將就緒。 您有查詢可以讀取您先前建立的類別和產品專案。
點讀取項目
在 Azure Cosmos DB 中擷取項目最簡單的方式是執行點讀取。 相較於查詢,點讀取會使用少量且可預測的 RU 數目。 在這裡,您將點讀取您所建立的頭盔單一類別項目。
返回 Program.cs 檔案。
為
gear-climb-helmets
建立新的 PartitionKey 執行個體。PartitionKey readKey = new("gear-climb-helmets");
使用 Container.ReadItemAsync,使用 id 屬性和分割區索引鍵值來點讀取特定項目。
ItemResponse<Category> readResponse = await container.ReadItemAsync<Category>( id: "91f79374-8611-4505-9c28-3bbbf1aa7df7", partitionKey: readKey );
使用 ItemResponse 類別的 Resource 屬性,取得序列化泛型型別。
Category readItem = readResponse.Resource;
輸出點讀取作業的唯一識別碼和要求費用。
Console.WriteLine($"[Point read item]:\t{readItem.Id}\t(RUs: {readResponse.RequestCharge})");
儲存Program.cs 檔案。
執行查詢
在需要多個項目的情況下,您可以使用查詢來尋找和擷取這些項目。 回想一下,我們使用 categoryId 資料分割索引鍵屬性,將項目分組到特定類別。 如果我們在查詢中包含該屬性,我們會有效地建置範圍設定為單一邏輯分割區的查詢。 現在,您將使用查詢來尋找帳篷類別中的所有項目。
在 Program.cs 中,為查詢
SELECT * FROM products p WHERE p.categoryId = 'gear-camp-tents'
建立新字串。 不過,針對 categoryId 篩選,請使用名為@partitionKey
的參數。string statement = "SELECT * FROM products p WHERE p.categoryId = @partitionKey";
使用查詢字串建立 QueryDefinition 類別的新執行個體。
var query = new QueryDefinition( query: statement );
使用 Fluent WithParameter 方法,將
gear-camp-tents
值指派給@partitionKey
參數。var parameterizedQuery = query.WithParameter("@partitionKey", "gear-camp-tents");
使用 Container.GetItemQueryIterator<> 擷取特定查詢的反覆運算器。
using FeedIterator<Product> feed = container.GetItemQueryIterator<Product>( queryDefinition: parameterizedQuery );
將查詢寫入主控台。
Console.WriteLine($"[Start query]:\t{statement}");
儲存Program.cs 檔案。
分頁查詢結果
Azure Cosmos DB 會自動將您的查詢結果分成可非同步擷取的頁面。 若要管理這些頁面,您必須以特定方式撰寫 C# 程式碼,以確保您擷取所有可用的結果頁面。 在這裡,您將使用 C# 中的 while 和 foreach 迴圈來逐一查看結果頁面。
在 Program.cs 中,建立名為 totalRequestCharge 的新 double 變數,將值設為
0
。double totalRequestCharge = 0d;
建立會逐一查看的 while 迴圈,直到摘要反覆運算器的 FeedIterator.HasMoreResults 屬性為 false 為止。
while (feed.HasMoreResults) { }
在 while 迴圈內,使用 FeedIterator.ReadNextAsync 方法取得結果的新頁面。
FeedResponse<Product> page = await feed.ReadNextAsync();
仍在 while 迴圈內部,使用 FeedResponse.RequestCharge 的值遞增要求總費用。
totalRequestCharge += page.RequestCharge;
仍在 while 迴圈內,建立新的 foreach 迴圈來逐一查看頁面中的實際項目。
foreach (Product item in page) { }
在 foreach 迴圈內,寫入主控台所傳回項目的 id 和 name 屬性。
Console.WriteLine($"[Returned item]:\t{item.Id}\t(Name: {item.Name ?? "N/A"})");
在 while 迴圈之外,寫入主控台所計算的要求總費用。
Console.WriteLine($"[Query metrics]:\t(RUs: {totalRequestCharge})");
提示
如果您不確定哪些程式碼應該在 while 和 foreach 迴圈內部或外部,請移至檢查您的工作中的檢閱程式碼區段。
儲存Program.cs 檔案。
檢查您的工作
您的應用程式現在會從容器讀取和查詢項目。 在這裡,您要執行應用程式,以便觀察這兩項作業的結果。
在終端中執行 .NET 應用程式:
dotnet run
觀察執行應用程式的輸出。 輸出應該會與此處範例相符:
... [Point read item]: 91f79374-8611-4505-9c28-3bbbf1aa7df7 (RUs: 1) [Start query]: SELECT * FROM products p WHERE p.categoryId = @partitionKey [Returned item]: 5df21ec5-813c-423e-9ee9-1a2aaead0be4 (Name: N/A) [Returned item]: e8dddee4-9f43-4d15-9b08-0d7f36adcac8 (Name: Cirroa Tent) [Returned item]: e6f87b8d-8cd7-4ade-a005-14d3e2fbd1aa (Name: Kuloar Tent) [Returned item]: f7653468-c4b8-47c9-97ff-451ee55f4fd5 (Name: Mammatin Tent) [Returned item]: 6e3b7275-57d4-4418-914d-14d1baca0979 (Name: Nimbolo Tent) [Query metrics]: (RUs: 2.94)
提示
此範例輸出中顯示的 RU 可能會因您的輸出而有所不同。
您是否注意到類別項目已成功還原序列化為您用於產品的類型? 因為類別項目沒有 name 屬性,所以該屬性會保留為其預設值。 類型檢查、架構管理和序列化/還原序列化都是應用程式可以完全管理用戶端的所有項目。