练习 - 连接到 Azure Cosmos DB for NoSQL

已完成

CosmosDbService 类包含服务的存根实现,类似于你在此模块中以前处理过的 OpenAiService 类。 相比之下,此类使用 .NET SDK for Azure Cosmos DB,其工作方式略有不同。

在本练习中,需要满足一些关键要求:

  • 导入适用于 Azure Cosmos DB for NoSQL 的 .NET SDK
  • 将 Azure Cosmos DB for NoSQL 终结点和键添加到应用程序设置
  • 使用各种成员和客户端实例修改服务类

导入 .NET SDK

Microsoft.Azure.Cosmos NuGet 包是一个类型化库,用于简化从 .NET 应用程序访问 Azure Cosmos DB for NoSQL 的过程。

  1. 打开新的终端。

  2. 使用 dotnet add package 从 NuGet 导入 Microsoft.Azure.Cosmos 包。

    dotnet add package Microsoft.Azure.Cosmos --version 3.*
    
  3. 再构建一个 .NET 项目。

    dotnet build
    
  4. 关闭终端。

添加应用程序设置

再次使用 appsettings.Development.json 文件为 Azure Cosmos DB for NoSQL 终结点和键提供当前值。

  1. 打开 appsettings.Development.json 文件。

  2. 在该文件中,创建另一个新的 JSON 对象,其中包含 CosmosDb 设置的占位符属性。

    {
      "OpenAi": {
        "Endpoint": "<your-azure-openai-endpoint>",
        "Key": "<your-azure-openai-key>"
      },
      "CosmosDb": {
      }
    }
    
  3. CosmosDb 属性中,为 EndpointKey 创建两个新属性。 使用之前在此项目中记录的 Azure Cosmos DB 终结点和键设置。

    {
      "OpenAi": {
        "Endpoint": "<your-azure-openai-endpoint>",
        "Key": "<your-azure-openai-key>"
      },
      "CosmosDb": {
        "Endpoint": "<your-azure-cosmos-db-endpoint>",
        "Key": "<your-azure-cosmos-db-key>"
      }
    }
    

    假设 Azure Cosmos DB 帐户的名称为 nybncrsna76fo-cosmos-nosql,键为 Aj2OSQqWhXfFzkITIi4MIbocWAAoBCUWnSPzHlQbDYA3TiyZCJlk8A6R1l6WqD45BxAG5vrsyQ4SCXEkPS1pLh==,则配置的 JSON 对象如以下示例所示。

    {
      "OpenAi": {
        "Endpoint": "<your-azure-openai-endpoint>",
        "Key": "<your-azure-openai-key>"
      },
      "CosmosDb": {
        "Endpoint": "https://nybncrsna76fo-cosmos-nosql.documents.azure.com:443/",
        "Key": "Aj2OSQqWhXfFzkITIi4MIbocWAAoBCUWnSPzHlQbDYA3TiyZCJlk8A6R1l6WqD45BxAG5vrsyQ4SCXEkPS1pLh=="
      }
    }
    

    注意

    此示例中的密钥是虚构的。

  4. 保存 appsettings.Development.json 文件。

添加所需的成员和客户端实例

最后,实现使用客户端访问 Azure Cosmos DB for NoSQL 所需的类变量和客户端。 对于此步骤,请使用 SDK 的客户端类在 CosmosDbService 类中实现类型 Container 的实例。

  1. 打开 Services/CosmosDbService.cs 文件。

  2. 为以下命名空间添加 using 指令。

    • Microsoft.Azure.Cosmos

    • Microsoft.Azure.Cosmos.Fluent

    using Microsoft.Azure.Cosmos;
    using Microsoft.Azure.Cosmos.Fluent;
    
  3. CosmosDbService 类中,添加新的 Container-typed variable named_container

    private readonly Container _container;
    
  4. 在构造函数中,添加 ArgumentNullException.ThrowIfNullOrEmpty 检查以在 endpointkey 参数为 null 时抛出错误。

    ArgumentNullException.ThrowIfNullOrEmpty(endpoint);
    ArgumentNullException.ThrowIfNullOrEmpty(key);
    
  5. 现在,创建一个 CosmosSerializationOptions 类型的 options 变量。 将该变量的 PropertyNamingPolicy 属性设置为 CosmosPropertyNamingPolicy.CamelCase

    CosmosSerializationOptions options = new()
    {
        PropertyNamingPolicy = CosmosPropertyNamingPolicy.CamelCase
    };
    

    注意

    设置此属性可确保 SDK 产生的 JSON 在 camel case 中序列化和反序列化,而不管它在 .NET 类中的相应属性如何。

  6. 使用前面指定的 CosmosClientBuilder 类、终结点、键和序列化选项创建一个名为 clientCosmosClient 类型新实例。

    CosmosClient client = new CosmosClientBuilder(endpoint, key)
        .WithSerializerOptions(options)
        .Build();
    
  7. 通过调用客户端变量的 GetDatabase 方法创建一个名为 databaseDatabase 类型可 null 新变量。

    Database? database = client?.GetDatabase(databaseName);
    
  8. 通过调用数据库变量的 GetContainer 方法创建另一个名为 containerContainer 类型可 null 变量。

    Container? container = database?.GetContainer(containerName);
    
  9. 最后,仅当构造函数的 container 变量不为 null 时,才将其变量分配给类的 _container 变量。 如果为 null,则抛出 ArgumentException

    _container = container ??
        throw new ArgumentException("Unable to connect to existing Azure Cosmos DB container or database.");
    

    提示

    此代码块使用 null 合并运算符检查变量在执行赋值之前是否为 null。

  10. 保存 Services/CosmosDbService.cs 文件。

检查工作

此时,构造函数应包含足够的逻辑来创建服务其余部分使用的容器实例。 由于该类尚未对容器执行任何操作,因此运行 Web 应用程序没有任何意义,但生成应用程序以确保代码没有任何遗漏或错误是有价值的。

  1. 打开新的终端。

  2. 生成 .NET 项目。

    dotnet build
    
  3. 观察生成输出并检查以确保没有任何生成错误。

    MSBuild version 17.5.1+f6fdcf537 for .NET
      Determining projects to restore...
      All projects are up-to-date for restore.
      cosmoschatgpt -> /workspaces/cosmosdb-chatgpt/bin/Debug/net8.0/cosmoschatgpt.dll
    
    Build succeeded.
        0 Warning(s)
        0 Error(s)
    
    Time Elapsed 00:00:06.45
    
  4. 关闭终端。