快速入门:适用于 .NET 的用于表的 Azure Cosmos DB

适用对象:

本快速入门介绍如何从 .NET 应用程序开始使用适用于表的 Azure Cosmos DB。 Azure Cosmos DB for Table 是一种无架构数据存储,允许应用程序在云中存储结构化表数据。 你将了解如何使用 Azure.Data.Tables 包 (NuGet) 在 Azure Cosmos DB 资源中创建表、行和执行基本任务。

注意

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

表 API 参考文档 | Azure.Data.Tables 包 (NuGet)

先决条件

设置

将此项目的开发容器部署到环境中。 然后,使用 Azure Developer CLI (azd) 创建 Azure Cosmos DB for Table 帐户并部署容器化示例应用程序。 示例应用程序使用客户端库来管理、创建、读取和查询示例数据。

在 GitHub Codespaces 中打开

在开发容器中打开

重要

GitHub 帐户包括使用免费的存储和核心小时数的权利。 有关详细信息,请参阅包含的 GitHub 帐户存储和核心小时数

  1. 在项目的根目录中打开终端。

  2. 使用 azd auth login 向 Azure Developer CLI 进行身份验证。 按照该工具指定的步骤,使用首选 Azure 凭据向 CLI 进行身份验证。

    azd auth login
    
  3. 使用 azd init 来初始化项目。

    azd init
    
  4. 在初始化期间,配置唯一的环境名称。

    提示

    环境名称也将用作目标资源组名称。 对于本快速入门,请考虑使用 msdocs-cosmos-db

  5. 使用 azd up 部署 Azure Cosmos DB 帐户。 Bicep 模板还部署示例 Web 应用程序。

    azd up
    
  6. 在预配过程中,选择订阅和所需位置。 等待预配过程完成。 此过程可能需要大约 5 分钟

  7. 预配 Azure 资源后,输出中将包含指向正在运行的 Web 应用程序的 URL。

    Deploying services (azd deploy)
    
      (✓) Done: Deploying service web
    - Endpoint: <https://[container-app-sub-domain].azurecontainerapps.io>
    
    SUCCESS: Your application was provisioned and deployed to Azure in 5 minutes 0 seconds.
    
  8. 使用控制台中的 URL 在浏览器中导航到 Web 应用程序。 观察正在运行的应用的输出。

    正在运行的 Web 应用程序的屏幕截图。

安装客户端库

客户端库可通过 NuGet 作为 Microsoft.Azure.Cosmos 包使用。

  1. 打开终端并导航到 /src/web 文件夹。

    cd ./src/web
    
  2. 使用 dotnet add package 安装 Azure.Data.Tables 包(如果尚未安装)。

    dotnet add package Azure.Data.Tables
    
  3. 另请安装 Azure.Identity 包(如果尚未安装)。

    dotnet add package Azure.Identity
    
  4. 打开并查看 src/web/Cosmos.Samples.Table.Quickstart.Web.csproj 文件,以验证 Microsoft.Azure.CosmosAzure.Identity 条目是否存在。

代码示例

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

使用以下表 API 类来与这些资源进行交互:

  • TableServiceClient - 此类提供使用适用于表的 Azure Cosmos DB 执行服务级别操作的方法。
  • TableClient - 此类允许与托管在 Azure Cosmos DB 表 API 中的表进行交互。
  • TableEntity - 此类是对表中行的引用,可用于管理属性和列数据。

验证客户端

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

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

// <using_directives> 
using Azure.Data.Tables;
// </using_directives>

// <client_credentials> 
// New instance of the TableClient class
TableServiceClient tableServiceClient = new TableServiceClient(Environment.GetEnvironmentVariable("COSMOS_CONNECTION_STRING"));
// </client_credentials>

// <create_table>
// New instance of TableClient class referencing the server-side table
TableClient tableClient = tableServiceClient.GetTableClient(
    tableName: "adventureworks"
);

await tableClient.CreateIfNotExistsAsync();
// </create_table>

// <create_object_add> 
// Create new item using composite key constructor
var prod1 = new Product()
{
    RowKey = "68719518388",
    PartitionKey = "gear-surf-surfboards",
    Name = "Ocean Surfboard",
    Quantity = 8,
    Sale = true
};

// Add new item to server-side table
await tableClient.AddEntityAsync<Product>(prod1);
// </create_object_add>

// <read_item> 
// Read a single item from container
var product = await tableClient.GetEntityAsync<Product>(
    rowKey: "68719518388",
    partitionKey: "gear-surf-surfboards"
);
Console.WriteLine("Single product:");
Console.WriteLine(product.Value.Name);
// </read_item>

// <query_items> 
// Read multiple items from container
var prod2 = new Product()
{
    RowKey = "68719518390",
    PartitionKey = "gear-surf-surfboards",
    Name = "Sand Surfboard",
    Quantity = 5,
    Sale = false
};

await tableClient.AddEntityAsync<Product>(prod2);

var products = tableClient.Query<Product>(x => x.PartitionKey == "gear-surf-surfboards");

Console.WriteLine("Multiple products:");
foreach (var item in products)
{
    Console.WriteLine(item.Name);
}
// </query_items>

使用构造函数定义 TableServiceClient 类的新实例,并使用 Environment.GetEnvironmentVariable 读取之前设置的连接字符串。

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

// <using_directives> 
using Azure.Data.Tables;
// </using_directives>

// <client_credentials> 
// New instance of the TableClient class
TableServiceClient tableServiceClient = new TableServiceClient(Environment.GetEnvironmentVariable("COSMOS_CONNECTION_STRING"));
// </client_credentials>

// <create_table>
// New instance of TableClient class referencing the server-side table
TableClient tableClient = tableServiceClient.GetTableClient(
    tableName: "adventureworks"
);

await tableClient.CreateIfNotExistsAsync();
// </create_table>

// <create_object_add> 
// Create new item using composite key constructor
var prod1 = new Product()
{
    RowKey = "68719518388",
    PartitionKey = "gear-surf-surfboards",
    Name = "Ocean Surfboard",
    Quantity = 8,
    Sale = true
};

// Add new item to server-side table
await tableClient.AddEntityAsync<Product>(prod1);
// </create_object_add>

// <read_item> 
// Read a single item from container
var product = await tableClient.GetEntityAsync<Product>(
    rowKey: "68719518388",
    partitionKey: "gear-surf-surfboards"
);
Console.WriteLine("Single product:");
Console.WriteLine(product.Value.Name);
// </read_item>

// <query_items> 
// Read multiple items from container
var prod2 = new Product()
{
    RowKey = "68719518390",
    PartitionKey = "gear-surf-surfboards",
    Name = "Sand Surfboard",
    Quantity = 5,
    Sale = false
};

await tableClient.AddEntityAsync<Product>(prod2);

var products = tableClient.Query<Product>(x => x.PartitionKey == "gear-surf-surfboards");

Console.WriteLine("Multiple products:");
foreach (var item in products)
{
    Console.WriteLine(item.Name);
}
// </query_items>

创建表

使用 TableServiceClient 类检索 TableClient 的实例。 如果新表尚不存在,请使用 TableClient 上的 TableClient.CreateIfNotExistsAsync 方法创建一个。 此方法将返回对现有或新创建的表的引用。

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

// <using_directives> 
using Azure.Data.Tables;
// </using_directives>

// <client_credentials> 
// New instance of the TableClient class
TableServiceClient tableServiceClient = new TableServiceClient(Environment.GetEnvironmentVariable("COSMOS_CONNECTION_STRING"));
// </client_credentials>

// <create_table>
// New instance of TableClient class referencing the server-side table
TableClient tableClient = tableServiceClient.GetTableClient(
    tableName: "adventureworks"
);

await tableClient.CreateIfNotExistsAsync();
// </create_table>

// <create_object_add> 
// Create new item using composite key constructor
var prod1 = new Product()
{
    RowKey = "68719518388",
    PartitionKey = "gear-surf-surfboards",
    Name = "Ocean Surfboard",
    Quantity = 8,
    Sale = true
};

// Add new item to server-side table
await tableClient.AddEntityAsync<Product>(prod1);
// </create_object_add>

// <read_item> 
// Read a single item from container
var product = await tableClient.GetEntityAsync<Product>(
    rowKey: "68719518388",
    partitionKey: "gear-surf-surfboards"
);
Console.WriteLine("Single product:");
Console.WriteLine(product.Value.Name);
// </read_item>

// <query_items> 
// Read multiple items from container
var prod2 = new Product()
{
    RowKey = "68719518390",
    PartitionKey = "gear-surf-surfboards",
    Name = "Sand Surfboard",
    Quantity = 5,
    Sale = false
};

await tableClient.AddEntityAsync<Product>(prod2);

var products = tableClient.Query<Product>(x => x.PartitionKey == "gear-surf-surfboards");

Console.WriteLine("Multiple products:");
foreach (var item in products)
{
    Console.WriteLine(item.Name);
}
// </query_items>

创建项

在表中创建新项的最简单方法是创建一个实现 ITableEntity 接口的类。 然后,可以将自己的属性添加到类中,以填充该表行中的数据列。

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

// <using_directives>
using Azure;
using Azure.Data.Tables;
// </using_directives>

// <type>
// C# record type for items in the table
public record Product : ITableEntity
{
    public string RowKey { get; set; } = default!;

    public string PartitionKey { get; set; } = default!;

    public string Name { get; init; } = default!;

    public int Quantity { get; init; }

    public bool Sale { get; init; }

    public ETag ETag { get; set; } = default!;

    public DateTimeOffset? Timestamp { get; set; } = default!;
}
// </type>

通过调用 TableClient.AddEntityAsync<T> 使用 Product 类在集合中创建某个项。

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

// <using_directives> 
using Azure.Data.Tables;
// </using_directives>

// <client_credentials> 
// New instance of the TableClient class
TableServiceClient tableServiceClient = new TableServiceClient(Environment.GetEnvironmentVariable("COSMOS_CONNECTION_STRING"));
// </client_credentials>

// <create_table>
// New instance of TableClient class referencing the server-side table
TableClient tableClient = tableServiceClient.GetTableClient(
    tableName: "adventureworks"
);

await tableClient.CreateIfNotExistsAsync();
// </create_table>

// <create_object_add> 
// Create new item using composite key constructor
var prod1 = new Product()
{
    RowKey = "68719518388",
    PartitionKey = "gear-surf-surfboards",
    Name = "Ocean Surfboard",
    Quantity = 8,
    Sale = true
};

// Add new item to server-side table
await tableClient.AddEntityAsync<Product>(prod1);
// </create_object_add>

// <read_item> 
// Read a single item from container
var product = await tableClient.GetEntityAsync<Product>(
    rowKey: "68719518388",
    partitionKey: "gear-surf-surfboards"
);
Console.WriteLine("Single product:");
Console.WriteLine(product.Value.Name);
// </read_item>

// <query_items> 
// Read multiple items from container
var prod2 = new Product()
{
    RowKey = "68719518390",
    PartitionKey = "gear-surf-surfboards",
    Name = "Sand Surfboard",
    Quantity = 5,
    Sale = false
};

await tableClient.AddEntityAsync<Product>(prod2);

var products = tableClient.Query<Product>(x => x.PartitionKey == "gear-surf-surfboards");

Console.WriteLine("Multiple products:");
foreach (var item in products)
{
    Console.WriteLine(item.Name);
}
// </query_items>

获取项

可使用 TableEntity.GetEntityAsync<T> 方法从表中检索特定项。 提供 partitionKeyrowKey 作为参数,用于识别正确的行以执行该项的快速点读取。

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

// <using_directives> 
using Azure.Data.Tables;
// </using_directives>

// <client_credentials> 
// New instance of the TableClient class
TableServiceClient tableServiceClient = new TableServiceClient(Environment.GetEnvironmentVariable("COSMOS_CONNECTION_STRING"));
// </client_credentials>

// <create_table>
// New instance of TableClient class referencing the server-side table
TableClient tableClient = tableServiceClient.GetTableClient(
    tableName: "adventureworks"
);

await tableClient.CreateIfNotExistsAsync();
// </create_table>

// <create_object_add> 
// Create new item using composite key constructor
var prod1 = new Product()
{
    RowKey = "68719518388",
    PartitionKey = "gear-surf-surfboards",
    Name = "Ocean Surfboard",
    Quantity = 8,
    Sale = true
};

// Add new item to server-side table
await tableClient.AddEntityAsync<Product>(prod1);
// </create_object_add>

// <read_item> 
// Read a single item from container
var product = await tableClient.GetEntityAsync<Product>(
    rowKey: "68719518388",
    partitionKey: "gear-surf-surfboards"
);
Console.WriteLine("Single product:");
Console.WriteLine(product.Value.Name);
// </read_item>

// <query_items> 
// Read multiple items from container
var prod2 = new Product()
{
    RowKey = "68719518390",
    PartitionKey = "gear-surf-surfboards",
    Name = "Sand Surfboard",
    Quantity = 5,
    Sale = false
};

await tableClient.AddEntityAsync<Product>(prod2);

var products = tableClient.Query<Product>(x => x.PartitionKey == "gear-surf-surfboards");

Console.WriteLine("Multiple products:");
foreach (var item in products)
{
    Console.WriteLine(item.Name);
}
// </query_items>

查询项

插入项后,还可以使用 TableClient.Query<T> 方法运行查询以获取与特定筛选器匹配的所有项。 此示例使用 Linq 语法按类别筛选产品,这是使用类型 ITableEntity 模型(如 Product 类)的好处。

注意

还可以使用 OData 语法查询项。 可在查询数据教程中看到此方法的示例。

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

// <using_directives> 
using Azure.Data.Tables;
// </using_directives>

// <client_credentials> 
// New instance of the TableClient class
TableServiceClient tableServiceClient = new TableServiceClient(Environment.GetEnvironmentVariable("COSMOS_CONNECTION_STRING"));
// </client_credentials>

// <create_table>
// New instance of TableClient class referencing the server-side table
TableClient tableClient = tableServiceClient.GetTableClient(
    tableName: "adventureworks"
);

await tableClient.CreateIfNotExistsAsync();
// </create_table>

// <create_object_add> 
// Create new item using composite key constructor
var prod1 = new Product()
{
    RowKey = "68719518388",
    PartitionKey = "gear-surf-surfboards",
    Name = "Ocean Surfboard",
    Quantity = 8,
    Sale = true
};

// Add new item to server-side table
await tableClient.AddEntityAsync<Product>(prod1);
// </create_object_add>

// <read_item> 
// Read a single item from container
var product = await tableClient.GetEntityAsync<Product>(
    rowKey: "68719518388",
    partitionKey: "gear-surf-surfboards"
);
Console.WriteLine("Single product:");
Console.WriteLine(product.Value.Name);
// </read_item>

// <query_items> 
// Read multiple items from container
var prod2 = new Product()
{
    RowKey = "68719518390",
    PartitionKey = "gear-surf-surfboards",
    Name = "Sand Surfboard",
    Quantity = 5,
    Sale = false
};

await tableClient.AddEntityAsync<Product>(prod2);

var products = tableClient.Query<Product>(x => x.PartitionKey == "gear-surf-surfboards");

Console.WriteLine("Multiple products:");
foreach (var item in products)
{
    Console.WriteLine(item.Name);
}
// </query_items>

运行代码

此应用创建 Azure Cosmos DB 表 API 表。 然后,该示例创建一个项,然后读取回完全相同的项。 最后,该示例创建第二个项,然后执行应返回多个项的查询。 对于每个步骤,该示例都会向控制台输出有关其已执行步骤的元数据。

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

dotnet run

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

Single product name: 
Yamba Surfboard
Multiple products:
Yamba Surfboard
Sand Surfboard

清理资源

当不再需要适用于表的 Azure Cosmos DB 帐户时,可以删除相应的资源组。

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

az group delete --name $resourceGroupName

后续步骤

在本快速入门中,你了解了如何使用 .NET SDK 创建适用于表的 Azure Cosmos DB 帐户、创建表和管理条目。 你现在可以深入探索 SDK,以了解如何在适用于表的 Azure Cosmos DB 资源中执行更高级的数据查询和管理任务。