練習 - 讀取和查詢項目

已完成

回想一下,您的應用程式預期都會將項目新增至 Azure Cosmos DB for NoSQL 容器,並將這些項目讀回驗證。 此時,您的應用程式已成功將項目新增至容器。 有兩種讀取項目的主要方式:執行點讀取,或執行查詢。

目前有三個主要需求:

  1. 使用唯一識別碼和資料分割索引鍵值來點讀取項目
  2. 使用簡單的查詢字串建立查詢
  3. 使用摘要反覆運算器分頁查詢的結果

Illustration of icons indicating data being queried using a query.

完成此練習之後,您的應用程式即將就緒。 您有查詢可以讀取您先前建立的類別和產品專案。

點讀取項目

在 Azure Cosmos DB 中擷取項目最簡單的方式是執行點讀取。 相較於查詢,點讀取會使用少量且可預測的 RU 數目。 在這裡,您將點讀取您所建立的頭盔單一類別項目。

  1. 返回 Program.cs 檔案。

  2. gear-climb-helmets 建立新的 PartitionKey 執行個體。

    PartitionKey readKey = new("gear-climb-helmets");
    
  3. 使用 Container.ReadItemAsync,使用 id 屬性和分割區索引鍵值來點讀取特定項目。

    ItemResponse<Category> readResponse = await container.ReadItemAsync<Category>(
        id: "91f79374-8611-4505-9c28-3bbbf1aa7df7",
        partitionKey: readKey
    );
    
  4. 使用 ItemResponse 類別的 Resource 屬性,取得序列化泛型型別。

    Category readItem = readResponse.Resource;
    
  5. 輸出點讀取作業的唯一識別碼和要求費用。

    Console.WriteLine($"[Point read item]:\t{readItem.Id}\t(RUs: {readResponse.RequestCharge})");    
    
  6. 儲存Program.cs 檔案。

執行查詢

在需要多個項目的情況下,您可以使用查詢來尋找和擷取這些項目。 回想一下,我們使用 categoryId 資料分割索引鍵屬性,將項目分組到特定類別。 如果我們在查詢中包含該屬性,我們會有效地建置範圍設定為單一邏輯分割區的查詢。 現在,您將使用查詢來尋找帳篷類別中的所有項目。

  1. Program.cs 中,為查詢 SELECT * FROM products p WHERE p.categoryId = 'gear-camp-tents' 建立新字串。 不過,針對 categoryId 篩選,請使用名為 @partitionKey 的參數。

    string statement = "SELECT * FROM products p WHERE p.categoryId = @partitionKey";
    
  2. 使用查詢字串建立 QueryDefinition 類別的新執行個體。

    var query = new QueryDefinition(
        query: statement
    );
    
  3. 使用 Fluent WithParameter 方法,將 gear-camp-tents 值指派給 @partitionKey 參數。

    var parameterizedQuery = query.WithParameter("@partitionKey", "gear-camp-tents");
    
  4. 使用 Container.GetItemQueryIterator<> 擷取特定查詢的反覆運算器。

    using FeedIterator<Product> feed = container.GetItemQueryIterator<Product>(
        queryDefinition: parameterizedQuery
    );
    
  5. 將查詢寫入主控台。

    Console.WriteLine($"[Start query]:\t{statement}");
    
  6. 儲存Program.cs 檔案。

分頁查詢結果

Azure Cosmos DB 會自動將您的查詢結果分成可非同步擷取的頁面。 若要管理這些頁面,您必須以特定方式撰寫 C# 程式碼,以確保您擷取所有可用的結果頁面。 在這裡,您將使用 C# 中的 whileforeach 迴圈來逐一查看結果頁面。

  1. Program.cs 中,建立名為 totalRequestCharge 的新 double 變數,將值設為 0

    double totalRequestCharge = 0d;
    
  2. 建立會逐一查看的 while 迴圈,直到摘要反覆運算器的 FeedIterator.HasMoreResults 屬性為 false 為止。

    while (feed.HasMoreResults)
    {
    }
    
  3. while 迴圈內,使用 FeedIterator.ReadNextAsync 方法取得結果的新頁面。

    FeedResponse<Product> page = await feed.ReadNextAsync();
    
  4. 仍在 while 迴圈內部,使用 FeedResponse.RequestCharge 的值遞增要求總費用。

    totalRequestCharge += page.RequestCharge;
    
  5. 仍在 while 迴圈內,建立新的 foreach 迴圈來逐一查看頁面中的實際項目。

    foreach (Product item in page)
    {
    }
    
  6. foreach 迴圈內,寫入主控台所傳回項目的 idname 屬性。

    Console.WriteLine($"[Returned item]:\t{item.Id}\t(Name: {item.Name ?? "N/A"})");
    
  7. while 迴圈之外,寫入主控台所計算的要求總費用。

    Console.WriteLine($"[Query metrics]:\t(RUs: {totalRequestCharge})");
    

    提示

    如果您不確定哪些程式碼應該在 whileforeach 迴圈內部或外部,請移至檢查您的工作中的檢閱程式碼區段。

  8. 儲存Program.cs 檔案。

檢查您的工作

您的應用程式現在會從容器讀取和查詢項目。 在這裡,您要執行應用程式,以便觀察這兩項作業的結果。

  1. 在終端中執行 .NET 應用程式:

    dotnet run
    
  2. 觀察執行應用程式的輸出。 輸出應該會與此處範例相符:

    ...
    [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 屬性,所以該屬性會保留為其預設值。 類型檢查、架構管理和序列化/還原序列化都是應用程式可以完全管理用戶端的所有項目。