快速入门:适用于 .NET 的 Azure Cosmos DB for NoSQL 客户端库

适用范围: NoSQL

开始使用适用于 .NET 的 Azure Cosmos DB 客户端库在帐户中创建数据库、容器和项。 请按照以下步骤安装程序包并试用基本任务的示例代码。

注意

示例代码片段在 GitHub 上作为 .NET 项目提供。

API 参考文档 | 库源代码 | 包 (NuGet) | 示例

先决条件

先决条件检查

  • 在终端或命令窗口中,运行 dotnet --version 以检查 .NET SDK 是否为 6.0 或更高版本。
  • 运行 az --version (Azure CLI) 或 Get-Module -ListAvailable AzureRM (Azure PowerShell),检查是否安装了适当的 Azure 命令行工具。

设置

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

创建 Azure Cosmos DB 帐户

本快速入门将使用 SQL API 创建单个 Azure Cosmos DB 帐户。

  1. 为 accountName、resourceGroupName 和 location 创建 shell 变量。

    # Variable for resource group name
    resourceGroupName="msdocs-cosmos-quickstart-rg"
    location="chinanorth"
    
    # Variable for account name with a randomly generated suffix
    let suffix=$RANDOM*$RANDOM
    accountName="msdocs-$suffix"
    
  2. 如果尚未登录,请使用 az login 命令登录到 Azure CLI。

  3. 使用 az group create 命令在订阅中创建新的资源组。

    az group create \
        --name $resourceGroupName \
        --location $location
    
  4. 使用 az cosmosdb create 命令创建具有默认设置的新 Azure Cosmos DB SQL API 帐户。

    az cosmosdb create \
        --resource-group $resourceGroupName \
        --name $accountName \
        --locations regionName=$location
    
  5. 使用 az cosmosdb show 命令获取帐户的 SQL API 终结点 URI。

    az cosmosdb show \
        --resource-group $resourceGroupName \
        --name $accountName \
        --query "documentEndpoint"
    
  6. 使用 az-cosmosdb-keys-list 命令从帐户的密钥列表中查找主密钥。

    az cosmosdb keys list \
        --resource-group $resourceGroupName \
        --name $accountName \
        --type "keys" \
        --query "primaryMasterKey"
    
  7. 记录 URI 和主密钥值。 稍后将使用这些凭据。

新建 .NET 应用

使用首选终端在空文件夹中创建新的 .NET 应用程序。 使用 dotnet new 命令指定 console 模板。

dotnet new console

安装包

Microsoft.Azure.Cosmos NuGet 包添加到 .NET 项目。 使用 dotnet add package 命令指定 NuGet 包的名称。

dotnet add package Microsoft.Azure.Cosmos

使用 dotnet build 命令生成项目。

dotnet build

确保生成成功且没有错误。 内部版本的预期输出应如下所示:

  Determining projects to restore...
  All projects are up-to-date for restore.
  dslkajfjlksd -> C:\Users\sidandrews\Demos\dslkajfjlksd\bin\Debug\net6.0\dslkajfjlksd.dll

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

配置环境变量

若要在代码中使用“URI”和“主密钥”值,请将其保存到运行应用程序的本地计算机上的新环境变量。 若要设置环境变量,请使用首选终端运行以下命令:

$env:COSMOS_ENDPOINT = "<cosmos-account-URI>"
$env:COSMOS_KEY = "<cosmos-account-PRIMARY-KEY>"

对象模型

在开始构建应用程序之前,我们先来了解 Azure Cosmos DB 中的资源层次结构。 Azure Cosmos DB 具有用于创建和访问资源的特定对象模型。 Azure Cosmos DB 在由帐户、数据库、容器和项组成的层次结构中创建资源。

Azure Cosmos DB 层次结构图表,其中包括帐户、数据库、容器和项。

顶部是显示 Azure Cosmos DB 帐户的层次结构示意图。 该帐户包含两个子数据库节点。 其中一个数据库节点包含两个子容器节点。 另一个数据库节点包含单个子容器节点。 该容器节点包含三个子项节点。

有关不同资源层次结构的详细信息,请参阅使用 Azure Cosmos DB 中的数据库、容器和项

使用以下 .NET 类与这些资源进行交互:

  • CosmosClient - 此类为 Azure Cosmos DB 服务提供客户端逻辑表示。 此客户端对象用于对服务进行配置和执行请求。
  • Database - 此类是对服务中可能存在或可能不存在的数据库的引用。 在尝试访问该数据库或对其执行操作时,会在服务器端验证该数据库。
  • Container - 此类是对服务中可能不存在的容器的引用。 在尝试使用该容器时,会在服务器端对其进行验证。
  • QueryDefinition - 此类表示 SQL 查询和任何查询参数。
  • FeedIterator<> - 此类表示一个迭代器,可跟踪当前页面的结果并获取新的结果页面。
  • FeedResponse<> - 此类表示来自迭代器的单页响应。 可使用 foreach 循环访问此类型。

代码示例

本文中所述的示例代码创建名为 adventureworks 的数据库和名为 products 的容器。 products 表被设计为包含产品详细信息,例如名称、类别、数量和销售指标。 每个产品还包含一个唯一标识符。

对于此示例代码,容器将使用类别作为逻辑分区键。

验证客户端

从项目目录中,打开 Program.cs 文件。 在编辑器中,为 Microsoft.Azure.Cosmos 添加 using 指令。

// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation.  All rights reserved.
// ------------------------------------------------------------

// <using_directives> 
using Microsoft.Azure.Cosmos;
// </using_directives>

// <client_credentials> 
// New instance of CosmosClient class
using CosmosClient client = new(
    accountEndpoint: Environment.GetEnvironmentVariable("COSMOS_ENDPOINT")!,
    authKeyOrResourceToken: Environment.GetEnvironmentVariable("COSMOS_KEY")!
);
// </client_credentials>

// <new_database> 
// Database reference with creation if it does not already exist
Database database = await client.CreateDatabaseIfNotExistsAsync(
    id: "cosmicworks"
);

Console.WriteLine($"New database:\t{database.Id}");
// </new_database>

// <new_container> 
// Container reference with creation if it does not alredy exist
Container container = await database.CreateContainerIfNotExistsAsync(
    id: "products",
    partitionKeyPath: "/categoryId",
    throughput: 400
);

Console.WriteLine($"New container:\t{container.Id}");
// </new_container>

// <new_item> 
// Create new object and upsert (create or replace) to container
Product newItem = new(
    id: "70b63682-b93a-4c77-aad2-65501347265f",
    categoryId: "61dba35b-4f02-45c5-b648-c6badc0cbd79",
    categoryName: "gear-surf-surfboards",
    name: "Yamba Surfboard",
    quantity: 12,
    sale: false
);

Product createdItem = await container.CreateItemAsync<Product>(
    item: newItem,
    partitionKey: new PartitionKey("61dba35b-4f02-45c5-b648-c6badc0cbd79")
);

Console.WriteLine($"Created item:\t{createdItem.id}\t[{createdItem.categoryName}]");
// </new_item>

// <read_item> 
// Point read item from container using the id and partitionKey
Product readItem = await container.ReadItemAsync<Product>(
    id: "70b63682-b93a-4c77-aad2-65501347265f",
    partitionKey: new PartitionKey("61dba35b-4f02-45c5-b648-c6badc0cbd79")
);
// </read_item>

// <query_items> 
// Create query using a SQL string and parameters
var query = new QueryDefinition(
    query: "SELECT * FROM products p WHERE p.categoryId = @categoryId"
)
    .WithParameter("@categoryId", "61dba35b-4f02-45c5-b648-c6badc0cbd79");

using FeedIterator<Product> feed = container.GetItemQueryIterator<Product>(
    queryDefinition: query
);

while (feed.HasMoreResults)
{
    FeedResponse<Product> response = await feed.ReadNextAsync();
    foreach (Product item in response)
    {
        Console.WriteLine($"Found item:\t{item.name}");
    }
}
// </query_items>

使用构造函数定义 CosmosClient 类的新实例,并使用 Environment.GetEnvironmentVariable 读取之前创建的两个环境变量。

// New instance of CosmosClient class
using CosmosClient client = new(
    accountEndpoint: Environment.GetEnvironmentVariable("COSMOS_ENDPOINT")!,
    authKeyOrResourceToken: Environment.GetEnvironmentVariable("COSMOS_KEY")!
);

有关创建 CosmosClient 实例的不同方法的详细信息,请参阅 Azure Cosmos DB for NoSQL 和 .NET 入门

创建数据库

如果新数据库尚不存在,请使用 CosmosClient.CreateDatabaseIfNotExistsAsync 方法创建一个。 此方法将返回对现有或新创建的数据库的引用。

// Database reference with creation if it does not already exist
Database database = await client.CreateDatabaseIfNotExistsAsync(
    id: "cosmicworks"
);

Console.WriteLine($"New database:\t{database.Id}");

有关创建数据库的详细信息,请参阅使用 .NET 在 Azure Cosmos DB for NoSQL 中创建数据库

创建容器

Database.CreateContainerIfNotExistsAsync 将创建一个新容器(如果它尚不存在)。 此方法还将返回对容器的引用。

// Container reference with creation if it does not alredy exist
Container container = await database.CreateContainerIfNotExistsAsync(
    id: "products",
    partitionKeyPath: "/categoryId",
    throughput: 400
);

Console.WriteLine($"New container:\t{container.Id}");

有关创建容器的详细信息,请参阅使用 .NET 在 Azure Cosmos DB for NoSQL 中创建容器

创建项

在容器中创建新项的最简单方法是首先生成包含要序列化为 JSON 的所有成员的 C# classrecord 类型。 在此示例中,C# 记录具有唯一标识符、分区键的 categoryId 字段以及额外的 categoryName、name、quantity 和 sale 字段。

// C# record representing an item in the container
public record Product(
    string id,
    string categoryId,
    string categoryName,
    string name,
    int quantity,
    bool sale
);

通过调用 Container.CreateItemAsync 在容器中创建某个项。

// Create new object and upsert (create or replace) to container
Product newItem = new(
    id: "70b63682-b93a-4c77-aad2-65501347265f",
    categoryId: "61dba35b-4f02-45c5-b648-c6badc0cbd79",
    categoryName: "gear-surf-surfboards",
    name: "Yamba Surfboard",
    quantity: 12,
    sale: false
);

Product createdItem = await container.CreateItemAsync<Product>(
    item: newItem,
    partitionKey: new PartitionKey("61dba35b-4f02-45c5-b648-c6badc0cbd79")
);

Console.WriteLine($"Created item:\t{createdItem.id}\t[{createdItem.categoryName}]");

有关创建、更新插入或替换项的详细信息,请参阅使用 .NET 在 Azure Cosmos DB for NoSQL 中创建项

获取项

在 Azure Cosmos DB 中,可同时使用唯一标识符 (id) 和分区键字段来执行点读取操作。 在 SDK 中,调用 Container.ReadItemAsync<> 并传入两个值,以返回 C# 类型的反序列化实例。

// Point read item from container using the id and partitionKey
Product readItem = await container.ReadItemAsync<Product>(
    id: "70b63682-b93a-4c77-aad2-65501347265f",
    partitionKey: new PartitionKey("61dba35b-4f02-45c5-b648-c6badc0cbd79")
);

有关读取项和分析响应的详细信息,请参阅使用 .NET 在 Azure Cosmos DB for NoSQL 中读取项

查询项

插入项后,可通过运行查询来获取与特定筛选器匹配的所有项。 此示例运行 SQL 查询:SELECT * FROM products p WHERE p.categoryId = "61dba35b-4f02-45c5-b648-c6badc0cbd79"。 此示例使用 QueryDefinition 类型和分区键筛选器的参数化查询表达式。 定义查询后,调用 Container.GetItemQueryIterator<> 以获取将管理结果页面的结果迭代器。 然后,结合使用 whileforeach 循环来检索结果页面,然后循环访问各个项。

// Create query using a SQL string and parameters
var query = new QueryDefinition(
    query: "SELECT * FROM products p WHERE p.categoryId = @categoryId"
)
    .WithParameter("@categoryId", "61dba35b-4f02-45c5-b648-c6badc0cbd79");

using FeedIterator<Product> feed = container.GetItemQueryIterator<Product>(
    queryDefinition: query
);

while (feed.HasMoreResults)
{
    FeedResponse<Product> response = await feed.ReadNextAsync();
    foreach (Product item in response)
    {
        Console.WriteLine($"Found item:\t{item.name}");
    }
}

运行代码

此应用创建 API for NoSQL 数据库和容器。 然后,该示例创建一个项,然后读取回完全相同的项。 最后,该示例发出仅应返回该单个项的查询。 对于每个步骤,该示例都会向控制台输出有关其已执行步骤的元数据。

要运行应用,请使用终端导航到应用程序目录并运行该应用程序。

dotnet run

应用的输出应类似于此示例:

New database:   adventureworks
New container:  products
Created item:   68719518391     [gear-surf-surfboards]

清理资源

当不再需要 Azure Cosmos DB SQL API 帐户时,可以删除相应的资源组。

使用 az group delete 命令删除资源组。

az group delete --name $resourceGroupName

后续步骤

在本快速入门中,你了解了如何使用 .NET SDK 创建 Azure Cosmos DB for NoSQL 帐户、数据库和容器。 现在可以更深入地了解教程,其中使用 .NET 控制台应用程序管理 Azure Cosmos DB for NoSQL 资源和数据。