クイックスタート: Azure Cosmos DB SQL API アカウント リソースを管理するための .NET V4 SDK (プレビュー) を使用したコンソール アプリを構築する

適用対象: 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 は、あらゆる規模に対応する、オープン API を備えた Microsoft の高速 NoSQL データベースです。 Azure Cosmos DB を使用すると、キー/値データベース、ドキュメント データベース、およびグラフ データベースをすばやく作成し、クエリを実行できます。 .NET 用の Azure Cosmos DB SQL API クライアント ライブラリを使用して、次のことを行います。

  • Azure Cosmos データベースとコンテナーを作成する
  • コンテナーにサンプル データを追加する
  • データにクエリを実行する
  • データベースを削除する

ライブラリのソース コード | パッケージ (NuGet)

前提条件

設定

このセクションでは、Azure Cosmos アカウントを作成し、.NET 用 Azure Cosmos DB SQL API クライアント ライブラリを使用してリソースを管理するプロジェクトを設定する手順について説明します。 この記事で説明するコード例では FamilyDatabase データベースと、そのデータベース内にファミリ メンバー (各ファミリ メンバーが項目) を作成します。 各ファミリ メンバーには Id, FamilyName, FirstName, LastName, Parents, Children, Address, などのプロパティがあります。 LastName プロパティは、コンテナーのパーティション キーとして使用されます。

Azure Cosmos アカウントを作成する

[Azure Cosmos DB を無料で試す] オプションを使用して Azure Cosmos アカウントを作成する場合は、種類が SQL API の Azure Cosmos DB アカウントを作成する必要があります。 Azure Cosmos DB テスト アカウントは既に作成されています。 アカウントを明示的に作成する必要はないため、このセクションをスキップして次のセクションに進むことができます。

独自の 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 ではストレージ アカウントも必要です。これはプロンプトが表示されたら作成できます。

次のコードの横にある [使ってみる] ボタンを選択し、 [Bash] モードを選択します。 [ストレージ アカウントを作成する] を選択して Cloud Shell にログインします。 次に、次のコードをコピーして 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, make 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 portal にサインインし、指定した名前の 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 portal から Azure Cosmos アカウントの資格情報をコピーする

サンプル アプリケーションは、Azure Cosmos アカウントに対する認証を行う必要があります。 認証するには、Azure Cosmos アカウントの資格情報をアプリケーションに渡す必要があります。 次の手順に従って、Azure Cosmos アカウントの資格情報を取得します。

  1. Azure portal にサインインします。

  2. Azure Cosmos アカウントに移動します。

  3. [キー] ウィンドウを開き、アカウントの [URI][プライマリ キー] をコピーします。 次の手順では、URI とキーの値を環境変数に追加します。

オブジェクト モデル

アプリケーションのビルドを開始する前に、Azure Cosmos DB のリソースの階層と、これらのリソースの作成とアクセスに使用されるオブジェクト モデルについて説明します。 Azure Cosmos DB によって、次の順序でリソースが作成されます。

  • Azure Cosmos アカウント
  • データベース
  • Containers
  • アイテム

さまざまなエンティティの階層の詳細については、Azure Cosmos DB のデータベース、コンテナー、および項目の操作に関する記事を参照してください。 これらのリソースとやり取りするには、以下の .NET クラスを使用します。

  • CosmosClient - このクラスは、Azure Cosmos DB サービスのクライアント側の論理表現を提供します。 このクライアント オブジェクトは、サービスに対する要求の構成と実行に使用されます。
  • CreateDatabaseIfNotExistsAsync - このメソッドによって、非同期操作としてデータベース リソースが (存在しない場合は) 作成されるか、(既に存在する場合は) 取得されます。
  • CreateContainerIfNotExistsAsync - このメソッドによって、非同期操作としてコンテナーが (存在しない場合は) 作成されるか、(既に存在する場合は) 取得されます。 応答から状態コードを確認して、コンテナーが新しく作成された (201) か、既存のコンテナーが返された (200) かを判断できます。
  • CreateItemAsync - このメソッドによって、コンテナー内に項目が作成されます。
  • UpsertItemAsync - このメソッドでは、アイテムがまだ存在しない場合、コンテナー内にアイテムが作成され、既に存在する場合、アイテムが置換されます。
  • GetItemQueryIterator - このメソッドにより、SQL ステートメントとパラメーター化された値を利用して Azure Cosmos データベースのコンテナーの下でアイテムに対するクエリが作成されます。
  • DeleteAsync - 指定されたデータベースを Azure Cosmos アカウントから削除します。 DeleteAsync メソッドでは、データベースのみが削除されます。

コード例

この記事で説明されているサンプル コードでは、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 メソッドを追加してファミリ項目を作成します。 CreateItemAsync または UpsertItemAsync のメソッドを使用し、アイテムを作成できます。

/// <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 クエリを直接使用してクエリを実行する方法を示しています。 "Anderson" ファミリの詳細を取得する 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 ファイルを保存します。

コードの実行

次に、アプリケーションをビルドして実行し、Azure Cosmos DB リソースを作成します。

dotnet run

アプリケーションを実行すると、次の出力が生成されます。 また、Azure portal にサインインして、リソースが作成されたことを確認することもできます。

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 portal にサインインし、Azure Cosmos アカウントで必要な項目を確認します。

リソースをクリーンアップする

必要がなくなったら、Azure CLI または Azure PowerShell を使用して、Azure Cosmos アカウントとそれに対応するリソース グループを削除できます。 次のコマンドは、Azure CLI を使用してリソース グループを削除する方法を示しています。

az group delete -g "myResourceGroup"

次のステップ

このクイックスタートでは、Azure Cosmos アカウントを作成し、.NET Core アプリを使用してデータベースとコンテナーを作成する方法を説明しました。 これで、次の記事の指示に従って Azure Cosmos アカウントに追加のデータをインポートできるようになりました。