Tutorial: Desenvolver um aplicativo de console .NET com o Azure Cosmos DB para NoSQL

APLICA-SE A: NoSQL

O SDK do Azure para .NET permite adicionar dados a uma API para contêiner NoSQL, operações individuais assíncronas ou um lote transacional. Este tutorial descreve o processo de criação de um novo aplicativo de console .NET que adiciona vários itens a um contêiner.

Neste tutorial, irá aprender a:

  • Criar um banco de dados usando a API para NoSQL
  • Criar um aplicativo de console .NET e adicionar o SDK do Azure para .NET
  • Adicionar itens individuais a uma API para contêiner NoSQL
  • Recuperar itens eficientes de uma API para contêiner NoSQL
  • Criar uma transação com alterações em lote para o contêiner API for NoSQL

Pré-requisitos

Criar API para recursos NoSQL

Primeiro, crie um banco de dados vazio na API existente para a conta NoSQL. Você cria um contêiner usando o SDK do Azure para .NET mais tarde.

  1. Navegue até sua conta existente da API para NoSQL no portal do Azure.

  2. No menu de recursos, selecione Chaves.

    Captura de ecrã de uma página de conta API para NoSQL. A opção Chaves é realçada no menu de recursos.

  3. Na página Chaves, observe e registre o valor dos campos URI e CHAVE PRIMÁRIA. Esses valores são usados durante todo o tutorial.

    Captura de ecrã da página Chaves com os campos URI e Chave Primária realçados.

  4. No menu de recursos, selecione Data Explorer.

    Captura de ecrã da opção Data Explorer realçada no menu de recursos.

  5. Na página Data Explorer, selecione a opção Novo Banco de Dados na barra de comandos.

    Captura de ecrã da opção Nova Base de Dados na barra de comandos do Explorador de Dados.

  6. Na caixa de diálogo Novo banco de dados, crie um novo contêiner com as seguintes configurações:

    Value
    ID da base de dados cosmicworks
    Tipo de taxa de transferência do banco de dados Manual
    Valor da taxa de transferência do banco de dados 400

    Captura de ecrã da caixa de diálogo Novo Base de Dados no Data Explorer com vários valores em cada campo.

  7. Selecione OK para criar o banco de dados.

Criar aplicativo de console .NET

Agora, você cria um novo aplicativo de console .NET e importa o SDK do Azure para .NET usando a Microsoft.Azure.Cosmos biblioteca do NuGet.

  1. Abra um terminal em um diretório vazio.

  2. Criar um novo aplicativo de console usando o console modelo interno

    dotnet new console --langVersion preview
    
  3. Adicione a versão 3.31.1-preview do Microsoft.Azure.Cosmos pacote do NuGet.

    dotnet add package Microsoft.Azure.Cosmos --version 3.31.1-preview
    
  4. Além disso, adicione a versão de pré-lançamento do System.CommandLine pacote do NuGet.

    dotnet add package System.CommandLine --prerelease
    
  5. Além disso, adicione o Humanizer pacote do NuGet.

    dotnet add package Humanizer
    
  6. Crie o projeto de aplicativo de console.

    dotnet build
    
  7. Abra o Visual Studio Code usando a pasta de projeto atual como o espaço de trabalho.

    Gorjeta

    Você pode executar code . no terminal para abrir o Visual Studio Code e abrir automaticamente o diretório de trabalho como o espaço de trabalho atual.

  8. Navegue até o arquivo Program.cs e abra-o . Exclua todo o código existente no arquivo.

  9. Adicione esse código ao arquivo para usar a biblioteca System.CommandLine para analisar a linha de comando para duas cadeias de caracteres passadas pelas --first opções e --last .

    using System.CommandLine;
    
    var command = new RootCommand();
    
    var nameOption = new Option<string>("--name") { IsRequired = true };
    var emailOption = new Option<string>("--email");
    var stateOption = new Option<string>("--state") { IsRequired = true };
    var countryOption = new Option<string>("--country") { IsRequired = true };
    
    command.AddOption(nameOption);
    command.AddOption(emailOption);
    command.AddOption(stateOption);
    command.AddOption(countryOption);
    
    command.SetHandler(
        handle: CosmosHandler.ManageCustomerAsync, 
        nameOption, 
        emailOption,
        stateOption,
        countryOption
    );
    
    await command.InvokeAsync(args);
    

    Nota

    Para este tutorial, não é totalmente importante que você entenda como o analisador de linha de comando funciona. O analisador tem quatro opções que podem ser especificadas quando o aplicativo está em execução. Três das opções são necessárias, pois serão usadas para construir os campos ID e chave de partição.

  10. Neste ponto, o projeto não será compilado, pois você ainda não definiu o método estático CosmosHandler.ManageCustomerAsync .

  11. Salve o arquivo Program.cs .

Adicionar itens a um contêiner usando o SDK

Em seguida, você usa operações individuais para adicionar itens ao contêiner API for NoSQL. Nesta seção, você define o CosmosHandler.ManageCustomerAsync método.

  1. Crie um novo arquivo CosmosHandler.cs .

  2. No arquivo CosmosHandler.cs, adicione uma nova diretiva using para os Humanizer namespaces e Microsoft.Azure.Cosmos .

    using Humanizer;
    using Microsoft.Azure.Cosmos;
    
  3. Crie uma nova classe estática chamada CosmosHandler.

    public static class CosmosHandler
    { }
    
  4. Apenas para validar que este aplicativo funciona, crie uma breve implementação do método estático ManageCustomerAsync para imprimir a entrada de linha de comando.

    public static async Task ManageCustomerAsync(string name, string email, string state, string country)
    {
        await Console.Out.WriteLineAsync($"Hello {name} of {state}, {country}!");
    }
    
  5. Salve o arquivo CosmosHandler.cs .

  6. De volta ao terminal, execute o aplicativo.

    dotnet run -- --name 'Mica Pereira' --state 'Washington' --country 'United States'
    
  7. A saída do comando deve ser uma saudação divertida.

    Hello Mica Pereira of Washington, United States!
    
  8. Regresse ao ficheiro CosmosHandler.cs .

  9. Dentro da classe estática CosmosHandler , adicione um novo private static readonly membro do tipo CosmosClient chamado _client.

    private static readonly CosmosClient _client;
    
  10. Crie um novo construtor estático para a CosmosHandler classe.

    static CosmosHandler()
    { }
    
  11. Dentro do construtor, crie uma nova instância da classe passando em dois parâmetros de cadeia de CosmosClient caracteres com os valores URI e PRIMARY KEY que você registrou anteriormente no laboratório. Armazene essa nova instância no _client membro.

    static CosmosHandler()
    {
        _client = new CosmosClient(
            accountEndpoint: "<uri>", 
            authKeyOrResourceToken: "<primary-key>"
        );
    }
    
  12. De volta à classe estática CosmosHandler , crie um novo método assíncrono chamado GetContainerAsync que retorna um Containerarquivo .

    private static async Task<Container> GetContainerAsync()
    { }
    
  13. Para as próximas etapas, adicione esse código dentro do GetContainerAsync método.

    1. Obtenha o cosmicworks banco de dados e armazene-o em uma variável chamada database.

      Database database = _client.GetDatabase("cosmicworks");
      
    2. Crie um novo genérico List<> de string valores dentro de uma lista de caminhos de chave de partição hierárquica e armazene-o em uma variável chamada keyPaths.

      List<string> keyPaths = new()
      {
          "/address/country",
          "/address/state"
      };
      
    3. Crie uma nova ContainerProperties variável com o nome do contêiner (customers) e a lista de caminhos de chave de partição.

      ContainerProperties properties = new(
          id: "customers",
          partitionKeyPaths: keyPaths
      );
      
    4. Use o CreateContainerIfNotExistsAsync método para fornecer as propriedades do contêiner e recuperá-lo. Esse método irá, de acordo com o nome, criar assincronamente o contêiner se ele ainda não existir no banco de dados. Retornar o resultado como a saída do GetContainerAsync método.

      return await database.CreateContainerIfNotExistsAsync(
          containerProperties: properties
      );
      
  14. Exclua todo o código dentro do ManageCustomerAsync método.

  15. Para as próximas etapas, adicione esse código dentro do ManageCustomerAsync método.

    1. Chame o método de forma assíncrona GetContainerAsync e armazene o resultado em uma variável chamada container.

      Container container = await GetContainerAsync();
      
    2. Crie uma nova variável chamada id que usa o Kebaberize método do Humanizer para transformar o parâmetro do name método.

      string id = name.Kebaberize();
      

      Nota

      O Kebaberize método substituirá todos os espaços por hífenes e converterá o texto para minúsculas.

    3. Crie um novo item digitado anônimo usando os nameparâmetros , statee country método e a id variável. Armazene o item como uma variável chamada customer.

      var customer = new {
          id = id,
          name = name,
          address = new {
              state = state,
              country = country
          }
      };
      
    4. Use o método assíncrono CreateItemAsync do contêiner para criar um novo item no contêiner e atribuir os metadados de resposta HTTP a uma variável chamada response.

      var response = await container.CreateItemAsync(customer);
      
    5. Escreva os response valores das StatusCode variáveis e RequestCharge propriedades no console. Escreva também o valor da id variável.

      Console.WriteLine($"[{response.StatusCode}]\t{id}\t{response.RequestCharge} RUs");
      
  16. Salve o arquivo CosmosHandler.cs .

  17. De volta ao terminal, execute o aplicativo novamente.

    dotnet run -- --name 'Mica Pereira' --state 'Washington' --country 'United States'
    
  18. A saída do comando deve incluir um status e uma taxa de solicitação para a operação.

    [Created]       mica-pereira    7.05 RUs
    

    Nota

    A taxa do seu pedido pode variar.

  19. Execute o aplicativo mais uma vez.

    dotnet run -- --name 'Mica Pereira' --state 'Washington' --country 'United States'
    
  20. Desta vez, o programa deve falhar. Se percorrer a mensagem de erro, verá que a falha ocorreu devido a um conflito no identificador exclusivo dos itens.

    Unhandled exception: Microsoft.Azure.Cosmos.CosmosException : Response status code does not indicate success: Conflict (409);Reason: (
        Errors : [
          "Resource with specified id or name already exists."
        ]
    );
    

Recuperar um item usando o SDK

Agora que você criou seu primeiro item no contêiner, pode usar o mesmo SDK para recuperar o item. Aqui, você consultará e apontará a leitura do item para comparar a diferença no consumo da unidade de solicitação (RU).

  1. Retorne ou abra o arquivo CosmosHandler.cs .

  2. Exclua todas as linhas de código do método, ManageCustomerAsync exceto as duas primeiras linhas.

    public static async Task ManageCustomerAsync(string name, string email, string state, string country)
    {
        Container container = await GetContainerAsync();
    
        string id = name.Kebaberize();
    }
    
  3. Para as próximas etapas, adicione esse código dentro do ManageCustomerAsync método.

    1. Use o método assíncrono CreateItemAsync do contêiner para criar um novo item no contêiner e atribuir os metadados de resposta HTTP a uma variável chamada response.

      var response = await container.CreateItemAsync(customer);
      
    2. Crie uma nova cadeia de caracteres nomeada sql com uma consulta SQL para recuperar itens em que um filtro (@id) corresponde.

      string sql = @"
      SELECT
          *
      FROM customers c
      WHERE c.id = @id
      ";
      
    3. Crie uma nova QueryDefinition variável chamada query passando na sql cadeia de caracteres como o único parâmetro de consulta. Além disso, use o WithParameter método fluido para aplicar o valor da variável id ao @id parâmetro.

      var query = new QueryDefinition(
          query: sql
      )
          .WithParameter("@id", id);
      
    4. Use o GetItemQueryIterator<> método genérico e a query variável para criar um iterador que obtém dados do Azure Cosmos DB. Armazene o iterador em uma variável chamada feed. Envolva toda essa expressão em uma instrução using para descartar o iterador mais tarde.

      using var feed = container.GetItemQueryIterator<dynamic>(
          queryDefinition: query
      );
      
    5. Chame assincronamente o ReadNextAsync feed método da variável e armazene o resultado em uma variável chamada response.

      var response = await feed.ReadNextAsync();
      
    6. Escreva os response valores das StatusCode variáveis e RequestCharge propriedades no console. Escreva também o valor da id variável.

      Console.WriteLine($"[{response.StatusCode}]\t{id}\t{response.RequestCharge} RUs");
      
  4. Salve o arquivo CosmosHandler.cs .

  5. De volta ao terminal, execute o aplicativo para ler o único item usando uma consulta SQL.

    dotnet run -- --name 'Mica Pereira' --state 'Washington' --country 'United States'
    
  6. A saída do comando deve indicar que a consulta exigiu várias unidades de solicitação (RUs).

    [OK]    mica-pereira    2.82 RUs
    
  7. De volta ao arquivo CosmosHandler.cs , exclua todas as linhas de código do ManageCustomerAsync método novamente, exceto as duas primeiras linhas.

    public static async Task ManageCustomerAsync(string name, string email, string state, string country)
    {
        Container container = await GetContainerAsync();
    
        string id = name.Kebaberize();
    }
    
  8. Para as próximas etapas, adicione esse código dentro do ManageCustomerAsync método.

    1. Crie uma nova instância de adicionando os state parâmetros e country como um valor de chave de partição de PartitionKeyBuilder várias partes.

      var partitionKey = new PartitionKeyBuilder()
          .Add(country)
          .Add(state)
          .Build();
      
    2. Use o método do ReadItemAsync<> contêiner para apontar a leitura do item do contêiner usando as id variáveis e partitionKey . Salve o resultado em uma variável chamada response.

      var response = await container.ReadItemAsync<dynamic>(
          id: id, 
          partitionKey: partitionKey
      );
      
    3. Escreva os response valores das StatusCode variáveis e RequestCharge propriedades no console. Escreva também o valor da id variável.

      Console.WriteLine($"[{response.StatusCode}]\t{id}\t{response.RequestCharge} RU");
      
  9. Salve o arquivo CosmosHandler.cs novamente.

  10. De volta ao terminal, execute o aplicativo mais uma vez para ler o item único.

    dotnet run -- --name 'Mica Pereira' --state 'Washington' --country 'United States'
    
  11. A saída do comando deve indicar que a consulta exigia uma única RU.

    [OK]    mica-pereira    1 RUs
    

Criar uma transação usando o SDK

Finalmente, você pega o item que criou, lê esse item e cria um item relacionado diferente como parte de uma única transação usando o SDK do Azure para .NET.

  1. Retorne ou abra o arquivo CosmosHandler.cs .

  2. Exclua essas linhas de código do ManageCustomerAsync método.

    var response = await container.ReadItemAsync<dynamic>(
        id: id, 
        partitionKey: partitionKey
    );
    
    Console.WriteLine($"[{response.StatusCode}]\t{id}\t{response.RequestCharge} RUs");
    
  3. Para as próximas etapas, adicione esse novo código dentro do ManageCustomerAsync método.

    1. Crie um novo item digitado anônimo usando os nameparâmetros , statee country método e a id variável. Armazene o item como uma variável chamada customerCart. Este item representa um carrinho de compras em tempo real para o cliente que está vazio no momento.

      var customerCart = new {
          id = $"{Guid.NewGuid()}",
          customerId = id,
          items = new string[] {},
          address = new {
              state = state,
              country = country
          }
      };
      
    2. Crie outro novo item digitado anônimo usando os nameparâmetros , statee country método e a id variável. Armazene o item como uma variável chamada customerCart. Este item representa informações de envio e contato para o cliente.

      var customerContactInfo = new {
          id = $"{id}-contact",
          customerId = id,
          email = email,
          location = $"{state}, {country}",
          address = new {
              state = state,
              country = country
          }
      };
      
    3. Crie um novo lote usando o método do CreateTransactionalBatch contêiner passando a partitionKey variável. Armazene o lote em uma variável chamada batch. Use métodos fluentes para executar as seguintes ações:

      Método Parâmetro
      ReadItem id variável string
      CreateItem customerCart variável de tipo anónimo
      CreateItem customerContactInfo variável de tipo anónimo
      var batch = container.CreateTransactionalBatch(partitionKey)
          .ReadItem(id)
          .CreateItem(customerCart)
          .CreateItem(customerContactInfo);
      
    4. Use o método do ExecuteAsync lote para iniciar a transação. Salve o resultado em uma variável chamada response.

      using var response = await batch.ExecuteAsync();
      
    5. Escreva os response valores das StatusCode variáveis e RequestCharge propriedades no console. Escreva também o valor da id variável.

      Console.WriteLine($"[{response.StatusCode}]\t{response.RequestCharge} RUs");
      
  4. Salve o arquivo CosmosHandler.cs novamente.

  5. De volta ao terminal, execute o aplicativo mais uma vez para ler o item único.

    dotnet run -- --name 'Mica Pereira' --state 'Washington' --country 'United States'
    
  6. A saída do comando deve mostrar as unidades de solicitação usadas para toda a transação.

    [OK]    16.05 RUs
    

    Nota

    A taxa do seu pedido pode variar.

Validar os dados finais no Data Explorer

Para concluir as coisas, use o Data Explorer no portal do Azure para exibir os dados e o contêiner criados neste tutorial.

  1. Navegue até sua conta existente da API para NoSQL no portal do Azure.

  2. No menu de recursos, selecione Data Explorer.

    Captura de ecrã da opção Data Explorer realçada no menu de recursos.

  3. Na página Data Explorer, expanda o cosmicworks banco de dados e selecione o customers contêiner.

    Captura de tela do nó de contêiner selecionado dentro do nó do banco de dados.

  4. Na barra de comandos, selecione Nova consulta SQL.

    Captura de ecrã da opção Nova Consulta SQL na barra de comandos do Data Explorer.

  5. No editor de consultas, observe essa cadeia de caracteres de consulta SQL.

    SELECT * FROM c
    
  6. Selecione Executar consulta para executar a consulta e observar os resultados.

    Captura de ecrã da opção 'Executar Consulta' na barra de comandos do Data Explorer.

  7. Os resultados devem incluir uma matriz JSON com três itens criados neste tutorial. Observe que todos os itens têm o mesmo valor de chave de partição hierárquica, mas campos de ID exclusivos. A saída de exemplo incluída é truncada para brevidade.

    [
      {
        "id": "mica-pereira",
        "name": "Mica Pereira",
        "address": {
          "state": "Washington",
          "country": "United States"
        },
        ...
      },
      {
        "id": "33d03318-6302-4559-b5c0-f3cc643b2f38",
        "customerId": "mica-pereira",
        "items": [],
        "address": {
          "state": "Washington",
          "country": "United States"
        },
        ...
      },
      {
        "id": "mica-pereira-contact",
        "customerId": "mica-pereira",
        "email": null,
        "location": "Washington, United States",
        "address": {
          "state": "Washington",
          "country": "United States"
        },
        ...
      }
    ]
    

Clean up resources (Limpar recursos)

Quando não for mais necessário, exclua o banco de dados usado neste tutorial. Para fazer isso, navegue até a página da conta, selecione Data Explorer, selecione o cosmicworks banco de dados e selecione Excluir.