快速入门:使用 .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 当前提供公共预览版。 此预览版在提供时没有附带服务级别协议,我们不建议将其用于生产工作负荷。 某些功能可能不受支持或者受限。

有关详细信息,请参阅适用于 Azure 预览版的补充使用条款

Azure Cosmos DB 是 21Vianet 的快速 NoSQL 数据库,具有适合于任何规模的开放式 API。 使用 Azure Cosmos DB,可以快速创建和查询键/值、文档和图形数据库。 使用适用于 .NET 的 Azure Cosmos DB SQL API 客户端库完成以下操作:

  • 创建 Azure Cosmos 数据库和容器
  • 向容器添加示例数据
  • 查询数据
  • 删除数据库

库源代码 | 包 (NuGet)

先决条件

设置

本部分指导你创建 Azure Cosmos 帐户,并设置使用适用于 .NET 的 Azure Cosmos DB SQL API 客户端库以管理资源的项目。

本文所述的示例代码创建 FamilyDatabase 数据库,并在该数据库中创建家庭成员。 每个家庭成员是一个项,具有 IdFamilyNameFirstNameLastNameParentsChildrenAddress 等属性。 LastName 属性用作容器的分区键。

创建 Azure Cosmos 帐户

如果你有自己的 Azure 订阅,则应显式创建 Azure Cosmos 帐户。 以下代码将创建具有会话一致性的 Azure Cosmos 帐户。 该帐户在 China EastChina North 中复制。

  1. 将以下代码复制并粘贴到 Azure 本地 Shell,然后运行该代码。 Azure Cosmos 帐户名必须是全局唯一的,因此请确保在运行该命令之前更新 mysqlapicosmosdb 值。

# Set variables for the new SQL API account, database, and container
resourceGroupName='myResourceGroup'
location='chinaeast'

# 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="China East" failoverPriority=0 --locations regionName="China North" failoverPriority=1 \
    --default-consistency-level "Session" \
    --enable-multiple-write-locations true

创建 Azure Cosmos 帐户需要一段时间。 操作成功后,可以看到确认输出。 登录到 Azure 门户,确认是否存在具有指定名称的 Azure Cosmos 帐户。

创建 .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

从 Microsoft 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 帐户
  • 数据库
  • 容器
  • Items

若要详细了解实体的层次结构,请参阅 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.cn: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 查询来执行查询。 获取 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.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.

通过登录到 Microsoft Azure 门户并查看 Azure Cosmos 帐户中的必需项,来验证是否已创建数据。

清理资源

不再需要 Azure Cosmos 帐户和相应资源组时,可以使用 Azure CLI 或 Azure PowerShell 将其删除。 以下命令显示如何使用 Azure CLI 删除资源组:

az group delete -g "myResourceGroup"

后续步骤

在本快速入门中,你已了解如何使用 .NET Core 应用创建 Azure Cosmos 帐户、数据库和容器。 现在可以使用以下文章中的说明将其他数据导入到 Azure Cosmos 帐户: