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

适用对象:

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

注意

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

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

先决条件

先决条件检查

  • 在终端或命令窗口中,运行 dotnet --list-sdks 以检查 .NET 6.x 是否是可用版本之一。
  • 运行 az --version (Azure CLI) 或 Get-Module -ListAvailable AzureRM (Azure PowerShell),检查是否安装了适当的 Azure 命令行工具。

设置

本部分将介绍如何创建 Azure Cosmos 帐户并设置使 表 API NuGet 包的项目。

创建 Azure Cosmos DB 帐户

本快速入门将使用表 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 randomnly 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帐户。

    az cosmosdb create \
        --resource-group $resourceGroupName \
        --name $accountName \
        --locations regionName=$location
        --capabilities EnableTable
    

获取表 API 连接字符串

  1. 使用 az cosmosdb list-connection-strings 命令,从帐户的连接字符串列表中查找表 API 连接字符串。

    az cosmosdb list-connection-strings \
        --resource-group $resourceGroupName \
        --name $accountName 
    
  2. 记录 主表连接字符串 值。 稍后将使用这些凭据。

新建 .NET 应用

使用首选终端在空文件夹中创建新的 .NET 应用程序。 使用 dotnet new console 创建新的控制台应用。

dotnet new console --output <app-name>

安装 NuGet 包

Azure.Data.Tables NuGet 包添加到新的 .NET 项目中。 使用 dotnet add package 命令指定 NuGet 包的名称。

dotnet add package Azure.Data.Tables

配置环境变量

若要在代码中使用“连接字符串”值,请在运行应用程序的本地计算机上设置此值。 若要设置环境变量,请使用首选终端运行以下命令:

$env:COSMOS_CONNECTION_STRING = "<cosmos-connection-string>"

代码示例

本文中所述的示例代码创建名为 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 资源中执行更高级的数据查询和管理任务。