共用方式為


教學課程:使用 Azure Cosmos DB for NoSQL 開發 .NET 主控台應用程式

適用於:NoSQL

利用適用於 .NET 的 Azure SDK,您可透過非同步個別作業交易式批次的方式,將資料新增至 API for NoSQL 容器。 本教學課程會逐步引導您建立新的 .NET 控制台應用程式,以將多個專案新增至容器。

在本教學課程中,您會了解如何:

  • 使用 API for NoSQL 建立資料庫
  • 建立 .NET 主控台應用程式,並新增適用於 .NET 的 Azure SDK
  • 將個別項目新增至 API for NoSQL 容器
  • 從 API for NoSQL 容器有效率地擷取項目
  • 為 API for NoSQL 容器建立批次變更的交易

必要條件

建立 API for NoSQL 資源

首先,在現有的 API for NoSQL 帳戶中建立空白資料庫。 您稍後會使用適用於 .NET 的 Azure SDK 建立容器。

  1. Azure 入口網站中瀏覽至您現有的 API for NoSQL 帳戶。

  2. 在 [資源] 功能表中,選取 [金鑰]

    適用於 NoSQL 帳戶的 API 頁面螢幕快照。[金鑰] 選項會在資源選單中反白顯示。

  3. 在 [金鑰] 頁面上,觀察並記錄 [URI] 和 [主索引鍵] 欄位的值。 這些值會在整個教學課程中使用。

    [金鑰] 頁面的螢幕快照,其中已醒目提示 [URI] 和 [主鍵] 字段。

  4. 在 [資源] 功能表中,選取 [資料總管]

    資源選單中醒目提示 [數據總管] 選項的螢幕快照。

  5. 在 [資料總管] 頁面上,選取命令列的 [新增資料庫] 選項。

    [數據總管] 命令列中 [新增資料庫] 選項的螢幕快照。

  6. 在 [新增資料庫] 對話方塊中,使用下列設定建立新的容器:

    資料庫識別碼 cosmicworks
    資料庫輸送量類型 手動
    資料庫輸送量數量 400

    [數據總管] 中 [新增資料庫] 對話框的螢幕快照,其中每個字段都有各種值。

  7. 選取 [確定] 以建立資料庫。

建立 .NET 主控台應用程式

現在,您會建立新的 .NET 控制台應用程式,並使用 NuGet 的連結庫匯入適用於 .NET 的 Microsoft.Azure.Cosmos Azure SDK。

  1. 在空的目錄中開啟終端機。

  2. 使用 console 內建範本建立新的主控台應用程式

    dotnet new console --langVersion preview
    
  3. 從 NuGet 新增 Microsoft.Azure.Cosmos 套件的 3.31.1-preview 版本。

    dotnet add package Microsoft.Azure.Cosmos --version 3.31.1-preview
    
  4. 也從 NuGet 新增 System.CommandLine 套件的 發行前版本。

    dotnet add package System.CommandLine --prerelease
    
  5. 也從 NuGet 新增 Humanizer 套件。

    dotnet add package Humanizer
    
  6. 建置主控台應用程式專案。

    dotnet build
    
  7. 使用目前的專案資料夾作為工作區,開啟 Visual Studio Code。

    提示

    您可以在終端機中執行 code . 開啟 Visual Studio Code,並自動將工作目錄開啟為目前的工作區。

  8. 瀏覽至 Program.cs 檔案並開啟。 刪除檔案中所有的現有程式碼。

  9. 將此程式碼新增至檔案,使用 System.CommandLine 程式庫剖析透過 --first--last 選項傳入的兩個字串命令列。

    using System.CommandLine;
    
    var command = new RootCommand();
    
    var nameOption = new Option<string>("--name") { IsRequired = true };
    var emailOption = new Option<string>("--email");
    var stateOption = new Option<string>("--state") { IsRequired = true };
    var countryOption = new Option<string>("--country") { IsRequired = true };
    
    command.AddOption(nameOption);
    command.AddOption(emailOption);
    command.AddOption(stateOption);
    command.AddOption(countryOption);
    
    command.SetHandler(
        handle: CosmosHandler.ManageCustomerAsync, 
        nameOption, 
        emailOption,
        stateOption,
        countryOption
    );
    
    await command.InvokeAsync(args);
    

    注意

    在本教學課程中,了解命令列剖析器的運作方式並不那麼重要。 剖析器有四個選項,可在應用程式執行時指定。 有三個選項是必要項,因為會用來建構 [識別碼] 和 [分割區索引鍵] 欄位。

  10. 此時不會建置專案,因為您尚未定義靜態 CosmosHandler.ManageCustomerAsync 方法。

  11. 儲存 Program.cs 檔案。

使用 SDK 將項目新增至容器

接下來,您會使用個別作業將專案新增至適用於 NoSQL 容器的 API。 在本節中,您會定義 CosmosHandler.ManageCustomerAsync 方法。

  1. 建立新的 CosmosHandler.cs 檔案。

  2. CosmosHandler.cs 檔案中,為 HumanizerMicrosoft.Azure.Cosmos 命名空間新增 using 指示詞。

    using Humanizer;
    using Microsoft.Azure.Cosmos;
    
  3. 建立名為 CosmosHandler 的新靜態類別。

    public static class CosmosHandler
    { }
    
  4. 只要驗證此應用程式可運作,請建立靜態 ManageCustomerAsync 方法的簡短實作,以列印命令行輸入。

    public static async Task ManageCustomerAsync(string name, string email, string state, string country)
    {
        await Console.Out.WriteLineAsync($"Hello {name} of {state}, {country}!");
    }
    
  5. [儲存] CosmosHandler.cs 檔案。

  6. 回到終端機,執行應用程式。

    dotnet run -- --name 'Mica Pereira' --state 'Washington' --country 'United States'
    
  7. 命令輸出應該是有趣的問候語。

    Hello Mica Pereira of Washington, United States!
    
  8. 返回 CosmosHandler.cs 檔案。

  9. 在靜態 CosmosHandler 類別內,新增名為 _client 的類型 CosmosClientprivate static readonly 成員。

    private static readonly CosmosClient _client;
    
  10. 建立 CosmosHandler 類別的新靜態建構函式。

    static CosmosHandler()
    { }
    
  11. 在建構函式中,建立 CosmosClient 類別的新執行個體,這個類別會以您之前在實驗室中記錄的 [URI] 和 [主索引鍵] 值傳入兩個字串參數。 將這個新執行個體儲存在 _client 成員中。

    static CosmosHandler()
    {
        _client = new CosmosClient(
            accountEndpoint: "<uri>", 
            authKeyOrResourceToken: "<primary-key>"
        );
    }
    
  12. 回到靜態 CosmosHandler 類別內,建立名為 GetContainerAsync 的新非同步方法,以傳回 Container

    private static async Task<Container> GetContainerAsync()
    { }
    
  13. 在後續步驟中,在 GetContainerAsync 方法中新增此程式碼。

    1. 取得 cosmicworks 資料庫,並儲存在名為 database 的變數中。

      Database database = _client.GetDatabase("cosmicworks");
      
    2. 在階層式分割區索引鍵路徑清單中建立 string 值的新泛型 List<>,並儲存在名為 keyPaths 的變數中。

      List<string> keyPaths = new()
      {
          "/address/country",
          "/address/state"
      };
      
    3. 建立以容器名稱 (customers) 命名的新 ContainerProperties 變數和分割區索引鍵路徑清單。

      ContainerProperties properties = new(
          id: "customers",
          partitionKeyPaths: keyPaths
      );
      
    4. 使用 CreateContainerIfNotExistsAsync 方法提供容器屬性並擷取容器。 如果資料庫內尚未有此容器,則這個方法會根據名稱,以非同步方式建立容器。 傳回結果作為 GetContainerAsync 方法的輸出。

      return await database.CreateContainerIfNotExistsAsync(
          containerProperties: properties
      );
      
  14. 刪除 ManageCustomerAsync 方法中的所有程式碼。

  15. 在後續步驟中,在 ManageCustomerAsync 方法中新增此程式碼。

    1. 以非同步方式呼叫 GetContainerAsync 方法,並將結果儲存在名為 container 的變數中。

      Container container = await GetContainerAsync();
      
    2. 建立名為 id 的新變數,其可使用 HumanizerKebaberize 方法來轉換 name 方法參數。

      string id = name.Kebaberize();
      

      注意

      Kebaberize 方法會將所有空格換成連字號,並將文字轉換為小寫。

    3. 使用 namestatecountry 方法參數以及 id 變數,建立新的匿名型別項目。 將項目儲存為名為 customer 的變數。

      var customer = new {
          id = id,
          name = name,
          address = new {
              state = state,
              country = country
          }
      };
      
    4. 使用容器的非同步 CreateItemAsync 方法,在容器中建立新項目,並將 HTTP 回應中繼資料指派給名為 response 的變數。

      var response = await container.CreateItemAsync(customer);
      
    5. response 變數的 StatusCodeRequestCharge 屬性值寫入主控台。 同時寫入 id 變數的值。

      Console.WriteLine($"[{response.StatusCode}]\t{id}\t{response.RequestCharge} RUs");
      
  16. [儲存] CosmosHandler.cs 檔案。

  17. 回到終端機,再次執行應用程式。

    dotnet run -- --name 'Mica Pereira' --state 'Washington' --country 'United States'
    
  18. 命令的輸出應該包含作業的狀態和要求費用。

    [Created]       mica-pereira    7.05 RUs
    

    注意

    您的要求費用可能會不一樣。

  19. 請再執行一次應用程式。

    dotnet run -- --name 'Mica Pereira' --state 'Washington' --country 'United States'
    
  20. 這次,程式應該會當機。 如果您捲動錯誤訊息,您會看到當機是因為專案的唯一標識符發生衝突。

    Unhandled exception: Microsoft.Azure.Cosmos.CosmosException : Response status code does not indicate success: Conflict (409);Reason: (
        Errors : [
          "Resource with specified id or name already exists."
        ]
    );
    

使用 SDK 擷取項目

在容器中建立第一個項目後,就可以使用相同的 SDK 來擷取項目。 此時,您將查詢並點讀取項目,以比較要求單位 (RU) 耗用量的差異。

  1. 返回或開啟 CosmosHandler.cs 檔案。

  2. 刪除 ManageCustomerAsync 方法中,除前兩行以外的所有程式碼。

    public static async Task ManageCustomerAsync(string name, string email, string state, string country)
    {
        Container container = await GetContainerAsync();
    
        string id = name.Kebaberize();
    }
    
  3. 在後續步驟中,在 ManageCustomerAsync 方法中新增此程式碼。

    1. 使用容器的非同步 CreateItemAsync 方法,在容器中建立新項目,並將 HTTP 回應中繼資料指派給名為 response 的變數。

      var response = await container.CreateItemAsync(customer);
      
    2. 使用 SQL 查詢建立名為 sql 的新字串,以擷取篩選 (@id) 相符的項目。

      string sql = @"
      SELECT
          *
      FROM customers c
      WHERE c.id = @id
      ";
      
    3. 建立名為 query 的新 QueryDefinition 變數,它會傳入 sql 字串作為唯一的查詢參數。 此外,也請使用 WithParameter 流體方法將變數 id 的值套用到 @id 參數。

      var query = new QueryDefinition(
          query: sql
      )
          .WithParameter("@id", id);
      
    4. 使用 GetItemQueryIterator<> 泛型方法和 query 變數來建立迭代器,以從 Azure Cosmos DB 取得資料。 將迭代器儲存在名為 feed 的變數中。 將這整個運算式包裝在 using 陳述式中,以便稍後處置迭代器。

      using var feed = container.GetItemQueryIterator<dynamic>(
          queryDefinition: query
      );
      
    5. 以非同步方式呼叫 feed 變數的 ReadNextAsync 方法,並將結果儲存在名為 response 的變數中。

      var response = await feed.ReadNextAsync();
      
    6. response 變數的 StatusCodeRequestCharge 屬性值寫入主控台。 同時寫入 id 變數的值。

      Console.WriteLine($"[{response.StatusCode}]\t{id}\t{response.RequestCharge} RUs");
      
  4. [儲存] CosmosHandler.cs 檔案。

  5. 回到終端機,執行應用程式以使用 SQL 查詢讀取單一項目。

    dotnet run -- --name 'Mica Pereira' --state 'Washington' --country 'United States'
    
  6. 命令的輸出應該指出查詢需要多個要求單位 (RU)。

    [OK]    mica-pereira    2.82 RUs
    
  7. 回到 CosmosHandler.cs 檔案,再次刪除 ManageCustomerAsync 方法中除前兩行以外的所有程式碼。

    public static async Task ManageCustomerAsync(string name, string email, string state, string country)
    {
        Container container = await GetContainerAsync();
    
        string id = name.Kebaberize();
    }
    
  8. 在後續步驟中,在 ManageCustomerAsync 方法中新增此程式碼。

    1. statecountry 參數新增為多部分分割區索引鍵值,以建立新的 PartitionKeyBuilder 執行個體。

      var partitionKey = new PartitionKeyBuilder()
          .Add(country)
          .Add(state)
          .Build();
      
    2. 使用容器的 ReadItemAsync<> 方法,使用 idpartitionKey 變數點讀取容器中的項目。 將結果儲存在名為 response 的變數中。

      var response = await container.ReadItemAsync<dynamic>(
          id: id, 
          partitionKey: partitionKey
      );
      
    3. response 變數的 StatusCodeRequestCharge 屬性值寫入主控台。 同時寫入 id 變數的值。

      Console.WriteLine($"[{response.StatusCode}]\t{id}\t{response.RequestCharge} RU");
      
  9. 再次 [儲存] CosmosHandler.cs 檔案。

  10. 回到終端機,再執行一次應用程式,以點讀取此單一項目。

    dotnet run -- --name 'Mica Pereira' --state 'Washington' --country 'United States'
    
  11. 命令的輸出應該會指出查詢只需要一個 RU。

    [OK]    mica-pereira    1 RUs
    

使用 SDK 建立交易

最後,您會採用您建立的專案、讀取該專案,並使用 Azure SDK for .NET 建立不同的相關專案作為單一交易的一部分。

  1. 返回或開啟 CosmosHandler.cs 檔案。

  2. 刪除 ManageCustomerAsync 方法中的以下程式碼。

    var response = await container.ReadItemAsync<dynamic>(
        id: id, 
        partitionKey: partitionKey
    );
    
    Console.WriteLine($"[{response.StatusCode}]\t{id}\t{response.RequestCharge} RUs");
    
  3. 在後續步驟中,在 ManageCustomerAsync 方法中新增此新的程式碼。

    1. 使用 namestatecountry 方法參數以及 id 變數,建立新的匿名型別項目。 將項目儲存為名為 customerCart 的變數。 此專案代表目前空白客戶的實時購物車。

      var customerCart = new {
          id = $"{Guid.NewGuid()}",
          customerId = id,
          items = new string[] {},
          address = new {
              state = state,
              country = country
          }
      };
      
    2. 使用 namestatecountry 方法參數以及 id 變數,建立另一個新的匿名型別項目。 將項目儲存為名為 customerCart 的變數。 此專案代表客戶的出貨和連絡資訊。

      var customerContactInfo = new {
          id = $"{id}-contact",
          customerId = id,
          email = email,
          location = $"{state}, {country}",
          address = new {
              state = state,
              country = country
          }
      };
      
    3. 使用容器的 CreateTransactionalBatch 方法建立新的批次,這個方法會傳入 partitionKey 變數。 將批次儲存在名為 batch 的變數中。 使用 Fluent 方法執行下列動作:

      方法 參數
      ReadItem id 字串變數
      CreateItem customerCart 匿名型別變數
      CreateItem customerContactInfo 匿名型別變數
      var batch = container.CreateTransactionalBatch(partitionKey)
          .ReadItem(id)
          .CreateItem(customerCart)
          .CreateItem(customerContactInfo);
      
    4. 使用批次的 ExecuteAsync 方法來啟動交易。 將結果儲存在名為 response 的變數中。

      using var response = await batch.ExecuteAsync();
      
    5. response 變數的 StatusCodeRequestCharge 屬性值寫入主控台。 同時寫入 id 變數的值。

      Console.WriteLine($"[{response.StatusCode}]\t{response.RequestCharge} RUs");
      
  4. 再次 [儲存] CosmosHandler.cs 檔案。

  5. 回到終端機,再執行一次應用程式,以點讀取此單一項目。

    dotnet run -- --name 'Mica Pereira' --state 'Washington' --country 'United States'
    
  6. 命令的輸出應該會顯示用於整個交易的要求單位。

    [OK]    16.05 RUs
    

    注意

    您的要求費用可能會不一樣。

驗證資料總管中的最終資料

若要總結專案,您可以使用 Azure 入口網站 中的數據總管來檢視您在本教學課程中建立的數據和容器。

  1. Azure 入口網站中瀏覽至您現有的 API for NoSQL 帳戶。

  2. 在 [資源] 功能表中,選取 [資料總管]

    資源選單中醒目提示 [數據總管] 選項的螢幕快照。

  3. 在 [資料總管] 頁面中,展開 cosmicworks 資料庫,然後選取 customers 容器。

    資料庫節點內所選容器節點的螢幕快照。

  4. 請在命令列中,選取 [新增 SQL 查詢]

    [數據總管] 命令行中 [新增 SQL 查詢] 選項的螢幕快照。

  5. 在查詢編輯器中,觀察此 SQL 查詢字串。

    SELECT * FROM c
    
  6. 選取 [執行查詢] 以執行查詢並觀察結果。

    數據總管命令列中 [執行查詢] 選項的螢幕快照。

  7. 結果應該包含 JSON 陣列,並包含在本教學課程中建立的三個項目。 觀察所有項目都有相同的階層式分割區索引鍵值,不是唯一的 [識別碼] 欄位。 所包含的範例輸出因簡潔而截斷。

    [
      {
        "id": "mica-pereira",
        "name": "Mica Pereira",
        "address": {
          "state": "Washington",
          "country": "United States"
        },
        ...
      },
      {
        "id": "33d03318-6302-4559-b5c0-f3cc643b2f38",
        "customerId": "mica-pereira",
        "items": [],
        "address": {
          "state": "Washington",
          "country": "United States"
        },
        ...
      },
      {
        "id": "mica-pereira-contact",
        "customerId": "mica-pereira",
        "email": null,
        "location": "Washington, United States",
        "address": {
          "state": "Washington",
          "country": "United States"
        },
        ...
      }
    ]
    

清除資源

如果不再需要本教學課程中使用的資料庫,請予以刪除。 若要這麼做,請瀏覽至帳戶頁面,選取 [資料總管]、選取 cosmicworks 資料庫,然後選取 [刪除]