快速入門:使用 .NET V4 SDK 建置主控台應用程式 (預覽),管理 Azure Cosmos DB SQL API 帳戶資源

適用於: SQL API

開始使用適用於 .NET 的 Azure Cosmos DB SQL API 用戶端程式庫。 請遵循本文中的步驟安裝 .NET V4 (Azure.Cosmos) 套件並建置應用程式。 然後,試用範例程式碼,對儲存在 Azure Cosmos DB 中的資料執行基本的建立、讀取、更新和刪除 (CRUD) 作業。

重要

適用於 Azure Cosmos DB 的 .NET V4 SDK 目前為公開預覽狀態。 此預覽版本沒有服務等級協定,不建議用於處理生產工作負載。 可能不支援特定功能,或可能已經限制功能。

如需詳細資訊,請參閱 Microsoft Azure 預覽版增補使用條款

Azure Cosmos DB 是 Microsoft 的快速 NoSQL 資料庫,可支援任何規模的開放式 API。 您可以使用 Azure Cosmos DB 快速地建立及查詢機碼/值、文件與圖形資料庫。 使用適用於 .NET 的 Azure Cosmos DB SQL API 用戶端程式庫來:

  • 建立 Azure Cosmos 資料庫與容器。
  • 將範例資料新增至容器。
  • 查詢資料。
  • 刪除資料庫。

程式庫原始程式碼 | 套件 (NuGet)

Prerequisites

設定

本節將逐步引導您建立 Azure Cosmos 帳戶,並設定專案以使用適用於 .NET 的 Azure Cosmos DB SQL API 用戶端程式庫來管理資源。

本文描述的範例程式碼會在該資料庫內建立 FamilyDatabase 資料庫與家庭成員。 每個家庭成員都是一個項目,而且具有 IdFamilyNameFirstNameLastNameParentsChildrenAddress 等屬性。 LastName 屬性會作為容器的資料分割索引鍵使用。

建立 Azure Cosmos 帳戶

如果您使用 [免費試用 Azure Cosmos DB] 選項建立 Azure Cosmos 帳戶,則必須建立類型為 SQL API 的 Azure Cosmos DB 帳戶。 已為您建立 Azure Cosmos 測試帳戶。 您不需要明確建立帳戶,因此您可以略過此小節並移至下一小節。

如果您有自己的 Azure 訂用帳戶,或已建立免費訂用帳戶,您應該明確地建立 Azure Cosmos 帳戶。 下列程式碼會建立包含工作階段一致性的 Azure Cosmos 帳戶。 該帳戶會在 South Central USNorth Central US 中複寫。

您可以使用 Azure Cloud Shell 來建立 Azure Cosmos 帳戶。 Azure Cloud Shell 是可經由瀏覽器存取的已驗證互動式殼層,應用在 Azure 資源管理上。 其可讓您彈性選擇最適合您工作方式的殼層體驗:Bash 或 PowerShell。

本快速入門使用 Bash。 Azure Cloud Shell 也需要儲存體帳戶。 您可以在提示出現後,建立一個儲存體帳戶。

  1. 選取下列程式碼旁邊的 [試試看] 按鈕,選擇 [Bash] 模式,然後選取 [建立儲存體帳戶] 並登入 Cloud Shell。

  2. 複製下列程式碼並貼到 Azure Cloud Shell 中來加以執行。 Azure Cosmos 帳戶名稱必須為全域唯一,請務必先更新 mysqlapicosmosdb 值,再執行命令。

    
    # Set variables for the new SQL API account, database, and container
    resourceGroupName='myResourceGroup'
    location='southcentralus'
    
    # The Azure Cosmos account name must be globally unique, so be sure to update the `mysqlapicosmosdb` value before you run the command
    accountName='mysqlapicosmosdb'
    
    # Create a resource group
    az group create \
        --name $resourceGroupName \
        --location $location
    
    # Create a SQL API Cosmos DB account with session consistency and multi-region writes enabled
    az cosmosdb create \
        --resource-group $resourceGroupName \
        --name $accountName \
        --kind GlobalDocumentDB \
        --locations regionName="South Central US" failoverPriority=0 --locations regionName="North Central US" failoverPriority=1 \
        --default-consistency-level "Session" \
        --enable-multiple-write-locations true
    
    

建立 Azure Cosmos 帳戶需要一些時間。 作業成功之後,您會看到確認輸出。 登入 Azure 入口網站,並驗證具有指定名稱的 Azure Cosmos 帳戶。 您可以在建立資源之後,關閉 [Azure Cloud Shell] 視窗。

建立 .NET 應用程式

在慣用的編輯器或 IDE 中建立 .NET 應用程式。 從本機電腦開啟 Windows 命令提示字元或終端機視窗。 您將會在命令提示字元或終端機中執行下一節中的所有命令。

執行下列 dotnet new 命令,建立名為 todo 的應用程式。 --langVersion 參數會在建立的專案檔中設定 LangVersion 屬性。

dotnet new console --langVersion:8 -n todo

使用下列命令,將目錄變更為新建立的應用程式資料夾,並建置應用程式:

cd todo
dotnet build

組建的預期輸出看起來應像這樣:

  Restore completed in 100.37 ms for C:\Users\user1\Downloads\CosmosDB_Samples\todo\todo.csproj.
  todo -> C:\Users\user1\Downloads\CosmosDB_Samples\todo\bin\Debug\netcoreapp3.0\todo.dll

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:34.17

安裝 Azure Cosmos DB 套件

若還在應用程式目錄中,請使用 dotnet add package 命令安裝適用於 .NET Core 的 Azure Cosmos DB 用戶端程式庫:

dotnet add package Azure.Cosmos --version 4.0.0-preview3

從 Azure 入口網站複製您的 Azure Cosmos 帳戶認證

範例應用程式需要驗證您的 Azure Cosmos 帳戶。 將 Azure Cosmos 帳戶認證傳遞給應用程式以執行驗證。 請依照下列步驟取得您的 Azure Cosmos 帳戶認證:

  1. 登入 Azure 入口網站

  2. 移至 Azure Cosmos 帳戶。

  3. 開啟 [金鑰] 窗格,然後複製您帳戶的 URI主索引鍵值。 在下一個程序中,您要將 URI 和索引鍵值新增至環境變數。

學習物件模型

在繼續建置應用程式之前,讓我們先看看 Azure Cosmos DB 的資源階層,以及用於建立及存取這些資源的物件模型。 Azure Cosmos DB 會依照下列順序建立資源:

  • Azure Cosmos 帳戶
  • 資料庫
  • 容器
  • 項目

若要深入了解實體階層,請參閱 Azure Cosmos DB 資源模型一文。 您將使用下列 .NET 類別與這些資源互動:

  • CosmosClient. 此類別提供適用於 Azure Cosmos DB 服務的用戶端邏輯表示法。 用戶端物件會用於設定及執行針對服務的要求。
  • CreateDatabaseIfNotExistsAsync. 此方法會建立 (如果不存在) 或取得 (如果已存在) 資料庫資源作為非同步作業。
  • CreateContainerIfNotExistsAsync. 此方法會建立 (如果不存在) 或取得 (如果已存在) 容器作為非同步作業。 您可以檢查來自回應的狀態碼,以判斷容器是新建立的 (201) 還是傳回的現有容器 (200)。
  • CreateItemAsync. 此方法會在容器內建立項目。
  • UpsertItemAsync. 此方法會在容器內建立項目 (如果尚未存在) 或取代項目 (如果已存在)。
  • GetItemQueryIterator. 此方法會使用具有參數化值的 SQL 陳述式,在 Azure Cosmos 資料庫的容器下建立項目查詢。
  • DeleteAsync. 此方法會刪除 Azure Cosmos 帳戶中的指定資料庫。

設定程式碼範例

此文章中描述的範例程式碼會在 Azure Cosmos DB 中建立家庭資料庫。 家庭資料庫包含家庭詳細資料,例如姓名、地址、位置、家長、子女和寵物。

將資料填入 Azure Cosmos 帳戶前,請先定義家庭項目的屬性。 在範例應用程式的根層級建立一個名為 Family.cs 的新類別,並在其中新增下列程式碼:

using System.Text.Json;
using System.Text.Json.Serialization;

namespace todo
{
    public class Family
    {
        [JsonPropertyName("id")]
        public string Id { get; set; }
        public string LastName { get; set; }
        public Parent[] Parents { get; set; }
        public Child[] Children { get; set; }
        public Address Address { get; set; }
        public bool IsRegistered { get; set; }
        public override string ToString()
        {
            return JsonSerializer.Serialize(this);
        }
    }

    public class Parent
    {
        public string FamilyName { get; set; }
        public string FirstName { get; set; }
    }

    public class Child
    {
        public string FamilyName { get; set; }
        public string FirstName { get; set; }
        public string Gender { get; set; }
        public int Grade { get; set; }
        public Pet[] Pets { get; set; }
    }

    public class Pet
    {
        public string GivenName { get; set; }
    }

    public class Address
    {
        public string State { get; set; }
        public string County { get; set; }
        public string City { get; set; }
    }
}

新增 using 指示詞並定義用戶端物件

在編輯器中開啟專案目錄的 Program.cs 檔案,並在應用程式的頂端新增下列 using 指示詞:

using System;
using System.Collections.Generic;
using System.Net;
using System.Threading.Tasks;
using Azure.Cosmos;

Program 類別中新增下列全域變數。 這些變數將包含端點和授權金鑰、資料庫名稱,以及您將建立的容器。 請務必根據環境取代端點和授權金鑰值。

private const string EndpointUrl = "https://<your-account>.documents.azure.com:443/";
private const string AuthorizationKey = "<your-account-key>";
private const string DatabaseId = "FamilyDatabase";
private const string ContainerId = "FamilyContainer";

最後,取代 Main 方法:

static async Task Main(string[] args)
{
    
    CosmosClient cosmosClient = new CosmosClient(EndpointUrl, AuthorizationKey);
    await Program.CreateDatabaseAsync(cosmosClient);
    await Program.CreateContainerAsync(cosmosClient);
    await Program.AddItemsToContainerAsync(cosmosClient);
    await Program.QueryItemsAsync(cosmosClient);
    await Program.ReplaceFamilyItemAsync(cosmosClient);
    await Program.DeleteFamilyItemAsync(cosmosClient);
    await Program.DeleteDatabaseAndCleanupAsync(cosmosClient);
}

建立資料庫

program.cs 類別內定義 CreateDatabaseAsync 方法。 如果資料庫不存在,此方法會建立 FamilyDatabase 資料庫。

/// <summary>
/// Create the database if it does not exist
/// </summary>
private static async Task CreateDatabaseAsync(CosmosClient cosmosClient)
{
    // Create a new database
    CosmosDatabase database = await cosmosClient.CreateDatabaseIfNotExistsAsync(Program.DatabaseId);
    Console.WriteLine("Created Database: {0}\n", database.Id);
}

建立容器

Program 類別內定義 CreateContainerAsync 方法。 如果容器不存在,此方法會建立 FamilyContainer 容器。

/// <summary>
/// Create the container if it does not exist. 
/// Specify "/LastName" as the partition key since we're storing family information, to ensure good distribution of requests and storage.
/// </summary>
/// <returns></returns>
private static async Task CreateContainerAsync(CosmosClient cosmosClient)
{
    // Create a new container
    CosmosContainer container = await cosmosClient.GetDatabase(Program.DatabaseId).CreateContainerIfNotExistsAsync(Program.ContainerId, "/LastName");
    Console.WriteLine("Created Container: {0}\n", container.Id);
}

建立項目

透過使用下列程式碼新增 AddItemsToContainerAsync 方法來建立家庭項目。 您可以使用 CreateItemAsyncUpsertItemAsync 方法來建立項目。

/// <summary>
/// Add Family items to the container
/// </summary>
private static async Task AddItemsToContainerAsync(CosmosClient cosmosClient)
{
    // Create a family object for the Andersen family
    Family andersenFamily = new Family
    {
        Id = "Andersen.1",
        LastName = "Andersen",
        Parents = new Parent[]
        {
            new Parent { FirstName = "Thomas" },
            new Parent { FirstName = "Mary Kay" }
        },
        Children = new Child[]
        {
            new Child
            {
                FirstName = "Henriette Thaulow",
                Gender = "female",
                Grade = 5,
                Pets = new Pet[]
                {
                    new Pet { GivenName = "Fluffy" }
                }
            }
        },
        Address = new Address { State = "WA", County = "King", City = "Seattle" },
        IsRegistered = false
    };

    CosmosContainer container = cosmosClient.GetContainer(Program.DatabaseId, Program.ContainerId);
    try
    {
        // Read the item to see if it exists.  
        ItemResponse<Family> andersenFamilyResponse = await container.ReadItemAsync<Family>(andersenFamily.Id, new PartitionKey(andersenFamily.LastName));
        Console.WriteLine("Item in database with id: {0} already exists\n", andersenFamilyResponse.Value.Id);
    }
    catch(CosmosException ex) when (ex.Status == (int)HttpStatusCode.NotFound)
    {
        // Create an item in the container representing the Andersen family. Note we provide the value of the partition key for this item, which is "Andersen"
        ItemResponse<Family> andersenFamilyResponse = await container.CreateItemAsync<Family>(andersenFamily, new PartitionKey(andersenFamily.LastName));

        // Note that after creating the item, we can access the body of the item with the Resource property off the ItemResponse.
        Console.WriteLine("Created item in database with id: {0}\n", andersenFamilyResponse.Value.Id);
    }

    // Create a family object for the Wakefield family
    Family wakefieldFamily = new Family
    {
        Id = "Wakefield.7",
        LastName = "Wakefield",
        Parents = new Parent[]
        {
            new Parent { FamilyName = "Wakefield", FirstName = "Robin" },
            new Parent { FamilyName = "Miller", FirstName = "Ben" }
        },
        Children = new Child[]
        {
            new Child
            {
                FamilyName = "Merriam",
                FirstName = "Jesse",
                Gender = "female",
                Grade = 8,
                Pets = new Pet[]
                {
                    new Pet { GivenName = "Goofy" },
                    new Pet { GivenName = "Shadow" }
                }
            },
            new Child
            {
                FamilyName = "Miller",
                FirstName = "Lisa",
                Gender = "female",
                Grade = 1
            }
        },
        Address = new Address { State = "NY", County = "Manhattan", City = "NY" },
        IsRegistered = true
    };

    // Create an item in the container representing the Wakefield family. Note we provide the value of the partition key for this item, which is "Wakefield"
    ItemResponse<Family> wakefieldFamilyResponse = await container.UpsertItemAsync<Family>(wakefieldFamily, new PartitionKey(wakefieldFamily.LastName));

    // Note that after creating the item, we can access the body of the item with the Resource property off the ItemResponse. We can also access the RequestCharge property to see the amount of RUs consumed on this request.
    Console.WriteLine("Created item in database with id: {0}\n", wakefieldFamilyResponse.Value.Id);
}

查詢項目

插入項目之後,您就可以執行查詢,以取得 Andersen 一家的詳細資料。 下列程式碼示範如何直接使用 SQL 查詢來執行查詢。 取得 Andersen 一家詳細資料的 SQL 查詢是 SELECT * FROM c WHERE c.LastName = 'Andersen'。 在 Program 類別中定義 QueryItemsAsync 方法,並在其中加入下列程式碼:

/// <summary>
/// Run a query (using Azure Cosmos DB SQL syntax) against the container
/// </summary>
private static async Task QueryItemsAsync(CosmosClient cosmosClient)
{
    var sqlQueryText = "SELECT * FROM c WHERE c.LastName = 'Andersen'";

    Console.WriteLine("Running query: {0}\n", sqlQueryText);

    CosmosContainer container = cosmosClient.GetContainer(Program.DatabaseId, Program.ContainerId);

    QueryDefinition queryDefinition = new QueryDefinition(sqlQueryText);

    List<Family> families = new List<Family>();

    await foreach (Family family in container.GetItemQueryIterator<Family>(queryDefinition))
    {
        families.Add(family);
        Console.WriteLine("\tRead {0}\n", family);
    }
}

取代項目

讀取家庭項目,然後使用下列程式碼新增 ReplaceFamilyItemAsync 方法來更新此項目:

/// <summary>
/// Replace an item in the container
/// </summary>
private static async Task ReplaceFamilyItemAsync(CosmosClient cosmosClient)
{
    CosmosContainer container = cosmosClient.GetContainer(Program.DatabaseId, Program.ContainerId);

    ItemResponse<Family> wakefieldFamilyResponse = await container.ReadItemAsync<Family>("Wakefield.7", new PartitionKey("Wakefield"));
    Family itemBody = wakefieldFamilyResponse;
    
    // update registration status from false to true
    itemBody.IsRegistered = true;
    // update grade of child
    itemBody.Children[0].Grade = 6;

    // replace the item with the updated content
    wakefieldFamilyResponse = await container.ReplaceItemAsync<Family>(itemBody, itemBody.Id, new PartitionKey(itemBody.LastName));
    Console.WriteLine("Updated Family [{0},{1}].\n \tBody is now: {2}\n", itemBody.LastName, itemBody.Id, wakefieldFamilyResponse.Value);
}

刪除項目

使用下列程式碼新增 DeleteFamilyItemAsync 方法來刪除家庭項目:

/// <summary>
/// Delete an item in the container
/// </summary>
private static async Task DeleteFamilyItemAsync(CosmosClient cosmosClient)
{
    CosmosContainer container = cosmosClient.GetContainer(Program.DatabaseId, Program.ContainerId);

    string partitionKeyValue = "Wakefield";
    string familyId = "Wakefield.7";

    // Delete an item. Note we must provide the partition key value and id of the item to delete
    ItemResponse<Family> wakefieldFamilyResponse = await container.DeleteItemAsync<Family>(familyId,new PartitionKey(partitionKeyValue));
    Console.WriteLine("Deleted Family [{0},{1}]\n", partitionKeyValue, familyId);
}

刪除資料庫

您可以使用下列程式碼新增 DeleteDatabaseAndCleanupAsync 方法來刪除資料庫:

/// <summary>
/// Delete the database and dispose of the Cosmos Client instance
/// </summary>
private static async Task DeleteDatabaseAndCleanupAsync(CosmosClient cosmosClient)
{
    CosmosDatabase database = cosmosClient.GetDatabase(Program.DatabaseId);
    DatabaseResponse databaseResourceResponse = await database.DeleteAsync();

    Console.WriteLine("Deleted Database: {0}\n", Program.DatabaseId);
}

新增所有必要的方法之後,請儲存 Program.cs 檔案。

執行程式碼

執行應用程式,以建立 Azure Cosmos DB 資源:

dotnet run

執行應用程式時會產生下列輸出:

Created Database: FamilyDatabase

Created Container: FamilyContainer

Created item in database with id: Andersen.1

Running query: SELECT * FROM c WHERE c.LastName = 'Andersen'

        Read {"id":"Andersen.1","LastName":"Andersen","Parents":[{"FamilyName":null,"FirstName":"Thomas"},{"FamilyName":null   "FirstName":"Mary Kay"}],"Children":[{"FamilyName":null,"FirstName":"Henriette Thaulow","Gender":"female","Grade":5,"Pets": [{"GivenName":"Fluffy"}]}],"Address":{"State":"WA","County":"King","City":"Seattle"},"IsRegistered":false}

Updated Family [Wakefield,Wakefield.7].
        Body is now: {"id":"Wakefield.7","LastName":"Wakefield","Parents":[{"FamilyName":"Wakefield","FirstName":"Robin"}   {"FamilyName":"Miller","FirstName":"Ben"}],"Children":[{"FamilyName":"Merriam","FirstName":"Jesse","Gender":"female","Grade":6   "Pets":[{"GivenName":"Goofy"},{"GivenName":"Shadow"}]},{"FamilyName":"Miller","FirstName":"Lisa","Gender":"female","Grade":1   "Pets":null}],"Address":{"State":"NY","County":"Manhattan","City":"NY"},"IsRegistered":true}

Deleted Family [Wakefield,Wakefield.7]

Deleted Database: FamilyDatabase

End of demo, press any key to exit.

您可以登入 Azure 入口網站並查看 Azure Cosmos 帳戶中的必要項目來驗證資料是否已建立。

清除資源

若不再需要 Azure Cosmos 帳戶與對應的資源群組,您可以使用 Azure CLI 或 Azure PowerShell 將其移除。 下列命令說明如何使用 Azure CLI 刪除資源群組:

az group delete -g "myResourceGroup"

後續步驟

在此快速入門中,您已了解如何使用 .NET Core 應用程式建立 Azure Cosmos 帳戶、建立資料庫以及建立容器。 您現在可以依照下列文章中的指示,將更多資料匯入 Azure Cosmos 帳戶:

正在嘗試為遷移至 Azure Cosmos DB 進行容量規劃嗎? 您可以使用現有資料庫叢集的相關資訊進行容量規劃。