Tutorial: Desenvolver um aplicativo Web do ASP.NET com o Azure Cosmos DB for NoSQL

APLICA-SE A: NoSQL

O SDK do Azure para .NET permite a consulta de dados em um contêiner da API para NoSQL usando LINQ em C# ou uma cadeia de caracteres de consulta SQL. Este tutorial explicará o processo de atualização de um aplicativo Web ASP.NET existente que usa dados de espaço reservado para, em vez disso, consultar a partir da API.

Neste tutorial, você aprenderá como:

  • Criar e popular um banco de dados e um contêiner usando a API para NoSQL
  • Criar um aplicativo Web ASP.NET com base em um modelo
  • Consultar dados do contêiner da API para NoSQL usando o SDK do Azure para .NET

Pré-requisitos

Criar API para recursos NoSQL

Primeiro, você irá criar um banco de dados e um contêiner na conta existente da API para NoSQL. Em seguida, você irá popular essa conta com dados usando a ferramenta dotnet cosmicworks.

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

  2. No menu de recursos, selecione Chaves.

    Captura de tela de uma página de conta da 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, PRIMARY KEY e PRIMARY CONNECTION STRING*. Esses valores serão usados ao longo do tutorial.

    Captura de tela da página Chaves com os campos URI, Primary Key e Primary Connection String realçados.

  4. No menu de recursos, selecione Data Explorer.

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

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

    Captura de tela da opção Novo contêiner na barra de comandos Data Explorer.

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

    Configuração Valor
    ID do banco de dados cosmicworks
    Tipo de taxa de transferência do banco de dados Manual
    Quantidade de taxa de transferência do banco de dados 4000
    ID do contêiner products
    Chave de partição /categoryId

    Captura de tela da caixa de diálogo Novo contêiner no Data Explorer com vários valores em cada campo.

    Importante

    Neste tutorial, primeiro dimensionaremos o banco de dados para até 4.000 RU/s na taxa de transferência compartilhada para maximizar o desempenho da migração de dados. Depois que a migração de dados for concluída, reduziremos verticalmente para 400 RU/s de taxa de transferência provisionada.

  7. Selecione OK para criar o banco de dados e o contêiner.

  8. Abra um terminal para executar comandos para preencher o contêiner com dados.

    Dica

    Você também pode usar o Azure Cloud Shell aqui.

  9. Instale uma versão de pré-lançamentoda ferramenta dotnet cosmicworks do NuGet.

    dotnet tool install --global cosmicworks  --prerelease
    
  10. Use a ferramenta cosmicworks para popular sua conta da API para NoSQL com dados de produto de exemplo usando os valores URI e PRIMARY KEY registrados anteriormente neste laboratório. Esses valores registrados serão usados para os parâmetros endpoint e key, respectivamente.

    cosmicworks \
        --datasets product \
        --endpoint <uri> \
        --key <primary-key>
    
  11. Observe a saída da ferramenta da linha de comando. Ela deve adicionar mais de 200 itens ao contêiner. A saída de exemplo incluída é truncada para fins de brevidade.

    ...
    Revision:       v4
    Datasets:
            product
    
    Database:       [cosmicworks]   Status: Created
    Container:      [products]      Status: Ready
    
    product Items Count:    295
    Entity: [9363838B-2D13-48E8-986D-C9625BE5AB26]  Container:products      Status: RanToCompletion
    ...
    Container:      [product]       Status: Populated
    
  12. Retorne à página Data Explorer da sua conta.

  13. Na seção Dados, expanda o nó do banco de dados cosmicworks e selecione Dimensionar.

    Captura de tela da opção Dimensionar no nó do banco de dados.

  14. Reduza a taxa de transferência de 4.000 para 400.

    Captura de tela das configurações de taxa de transferência para o banco de dados reduzida para 400 RU/s.

  15. Na barra de comandos, selecione Salvar.

    Captura de tela da opção Salvar na barra de comandos Data Explorer.

  16. Na seção Dados, expanda e selecione o nó de contêiner dos produtos.

    Captura de tela do nó de contêiner expandido no nó do banco de dados.

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

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

  18. No editor de consultas, adicione essa cadeia de caracteres de consulta SQL.

    SELECT
      p.sku,
      p.price
    FROM products p
    WHERE p.price < 2000
    ORDER BY p.price DESC
    
  19. Selecione Executar Consulta para executar a consulta e observar os resultados.

    Captura de tela da opção Executar Consulta na barra de comandos Data Explorer.

  20. Os resultados devem ser uma matriz paginada de todos os itens no contêiner com um valor price inferior a 2.000 classificados do preço mais alto para o mais baixo. Para fins de brevidade, um subconjunto da saída é incluído aqui.

    [
      {
        "sku": "BK-R79Y-48",
        "price": 1700.99
      },
      ...
      {
        "sku": "FR-M94B-46",
        "price": 1349.6
      },
    ...
    
  21. Substitua o conteúdo do editor de consultas por essa consulta e selecione Executar consulta novamente para observar os resultados.

    SELECT
      p.name,
      p.categoryName,
      p.tags
    FROM products p
    JOIN t IN p.tags
    WHERE t.name = "Tag-32"
    
  22. Os resultados devem ser uma matriz menor de itens filtrados para conter apenas itens que incluem pelo menos uma marca com um valor nome de Tag-32. Novamente, um subconjunto da saída é incluído aqui para fins de brevidade.

    ...
    {
    "name": "ML Mountain Frame - Black, 44",
    "categoryName": "Components, Mountain Frames",
    "tags": [
        {
        "id": "18AC309F-F81C-4234-A752-5DDD2BEAEE83",
        "name": "Tag-32"
        }
    ]
    },
    ...
    

Criar aplicativo Web ASP.NET

Agora você criará um novo aplicativo Web ASP.NET usando um modelo de projeto de exemplo. Em seguida, você explorará o código-fonte e executará o exemplo para se familiarizar com o aplicativo antes de adicionar a conectividade do Azure Cosmos DB usando o SDK do Azure para .NET.

Importante

Este tutorial efetua pull transparente de pacotes do NuGet. Você pode usar dotnet nuget list source para verificar as origens do pacote. Se você não tiver o NuGet como uma origem do pacote, use dotnet nuget add source para instalar o site como uma origem.

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

  2. Instale o pacote de modelo de projeto cosmicworks.template.web do NuGet.

    dotnet new install cosmicworks.template.web
    
  3. Crie um novo projeto de aplicativo Web usando o modelo recém-instalado dotnet new cosmosdbnosql-webapp.

    dotnet new cosmosdbnosql-webapp
    
  4. Compile e execute o projeto do aplicativo Web.

    dotnet run
    
  5. Observe a saída do comando de execução. A saída deve incluir uma lista de portas e URLs em que o aplicativo está em execução.

    ...
    info: Microsoft.Hosting.Lifetime[14]
          Now listening on: http://localhost:5000
    info: Microsoft.Hosting.Lifetime[14]
          Now listening on: https://localhost:5001
    info: Microsoft.Hosting.Lifetime[0]
          Application started. Press Ctrl+C to shut down.
    info: Microsoft.Hosting.Lifetime[0]
          Hosting environment: Production
    ...
    
  6. Abra um novo navegador e acesse o aplicativo Web em execução. Observe todas as três páginas do aplicativo em execução.

    Captura de tela do aplicativo Web de exemplo em execução com dados de espaço reservado.

  7. Interrompa o aplicativo em execução encerrando o processo em execução.

    Dica

    Use o comando Ctrl+C para interromper um processo em execução. Como alternativa, você pode fechar e reabrir o terminal.

  8. Abra o Visual Studio Code usando a pasta de projeto atual como o workspace.

    Dica

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

  9. Navegue até o arquivo Services/ICosmosService.cs e abra-o. Observe as implementações do método padrão RetrieveActiveProductsAsync e RetrieveAllProductsAsync. Esses métodos criam uma lista estática de produtos a serem usados ao executar o projeto pela primeira vez. Um exemplo truncado de um dos métodos é fornecido aqui.

    public async Task<IEnumerable<Product>> RetrieveActiveProductsAsync()
    {
        await Task.Delay(1);
    
        return new List<Product>()
        {
            new Product(id: "baaa4d2d-5ebe-45fb-9a5c-d06876f408e0", categoryId: "3E4CEACD-D007-46EB-82D7-31F6141752B2", categoryName: "Components, Road Frames", sku: "FR-R72R-60", name: """ML Road Frame - Red, 60""", description: """The product called "ML Road Frame - Red, 60".""", price: 594.83000000000004m),
           ...
            new Product(id: "d5928182-0307-4bf9-8624-316b9720c58c", categoryId: "AA5A82D4-914C-4132-8C08-E7B75DCE3428", categoryName: "Components, Cranksets", sku: "CS-6583", name: """ML Crankset""", description: """The product called "ML Crankset".""", price: 256.49000000000001m)
        };
    }
    
  10. Navegue até o arquivo Services/CosmosService.cs e abra-o. Observe a implementação atual da classe CosmosService. Essa classe implementa a interface ICosmosService, mas não substitui nenhum método. Nesse contexto, a classe usará a implementação de interface padrão até que uma substituição da implementação seja fornecida na interface.

    public class CosmosService : ICosmosService
    { }
    
  11. Por fim, navegue até o arquivo Models/Product.cs e abra-o. Observe o tipo de registro definido neste arquivo. Esse tipo será usado nas consultas ao longo deste tutorial.

    public record Product(
        string id,
        string categoryId,
        string categoryName,
        string sku,
        string name,
        string description,
        decimal price
    );
    

Consultar os dados usando o .NET SDK

Em seguida, você adicionará o SDK do Azure para .NET a este projeto de exemplo e usará a biblioteca para consultar dados do contêiner da API para NoSQL.

  1. De volta ao terminal, adicione o pacote Microsoft.Azure.Cosmos do NuGet.

    dotnet add package Microsoft.Azure.Cosmos
    
  2. Compile o projeto.

    dotnet build
    
  3. De volta ao Visual Studio Code, navegue novamente até o arquivo Services/CosmosService.cs.

  4. Adicione uma nova diretiva using para os namespaces Microsoft.Azure.Cosmos e Microsoft.Azure.Cosmos.Linq.

    using Microsoft.Azure.Cosmos;
    using Microsoft.Azure.Cosmos.Linq;
    
  5. Na classe CosmosService, adicione um novo private readonly membro do tipo CosmosClient chamado _client.

    private readonly CosmosClient _client;
    
  6. Crie um novo construtor vazio para a classe CosmosService.

    public CosmosService()
    { }
    
  7. No construtor, crie uma nova instância da classe CosmosClient passando em um parâmetro de cadeia de caracteres com o valor PRIMARY CONNECTION STRING que você registrou anteriormente no laboratório. Armazene essa nova instância no membro _client.

    public CosmosService()
    { 
        _client = new CosmosClient(
            connectionString: "<primary-connection-string>"
        );
    }
    
  8. De volta à classe CosmosService, crie uma nova propriedade private do tipo Container chamada container. Defina o acessador get para retornar o banco de dados cosmicworks e o contêiner products.

    private Container container
    {
        get => _client.GetDatabase("cosmicworks").GetContainer("products");
    }
    
  9. Crie um novo método assíncrono chamado RetrieveAllProductsAsync que retorna um IEnumerable<Product>.

    public async Task<IEnumerable<Product>> RetrieveAllProductsAsync()
    { }
    
  10. Para as próximas etapas, adicione esse código dentro do método RetrieveAllProductsAsync.

    1. Use o método genérico GetItemLinqQueryable<> para obter um objeto do tipo IQueryable<> que você pode usar para construir uma LINQ (consulta integrada à linguagem). Armazene o objeto em uma variável chamada queryable.

      var queryable = container.GetItemLinqQueryable<Product>();
      
    2. Construa uma consulta LINQ usando os métodos de extensão Where e OrderByDescending. Use o método de extensão ToFeedIterator para criar um iterador para obter dados do Azure Cosmos DB e armazenar o iterador em uma variável chamada feed. Encapsule toda essa expressão em uma instrução using a fim de descartar o iterador posteriormente.

      using FeedIterator<Product> feed = queryable
          .Where(p => p.price < 2000m)
          .OrderByDescending(p => p.price)
          .ToFeedIterator();
      
    3. Crie uma nova variável chamada results usando o tipo genérico List<>.

      List<Product> results = new();
      
    4. Crie um loop while que será iterado até que a propriedade HasMoreResults da variável feed retorne false. Esse loop garantirá que você faça loop em todas as páginas de resultados do lado do servidor.

      while (feed.HasMoreResults)
      { }
      
    5. No loop while, chame de forma assíncrona o método ReadNextAsync da variável feed e armazene o resultado em uma variável chamada response.

      while (feed.HasMoreResults)
      {
          var response = await feed.ReadNextAsync();
      }
      
    6. Ainda dentro do loop while, use um loop foreach para percorrer cada item na resposta e adicioná-los à lista results.

      while (feed.HasMoreResults)
      {
          var response = await feed.ReadNextAsync();
          foreach (Product item in response)
          {
              results.Add(item);
          }
      }
      
    7. Retorne a lista results como a saída do método RetrieveAllProductsAsync.

      return results;
      
  11. Crie um novo método assíncrono chamado RetrieveActiveProductsAsync que retorna um IEnumerable<Product>.

    public async Task<IEnumerable<Product>> RetrieveActiveProductsAsync()
    { }
    
  12. Para as próximas etapas, adicione esse código dentro do método RetrieveActiveProductsAsync.

    1. Crie uma nova cadeia de caracteres chamada sql com uma consulta SQL para recuperar vários campos em que um filtro (@tagFilter) é aplicado à matriz de marcas de cada item.

      string sql = """
      SELECT
          p.id,
          p.categoryId,
          p.categoryName,
          p.sku,
          p.name,
          p.description,
          p.price,
          p.tags
      FROM products p
      JOIN t IN p.tags
      WHERE t.name = @tagFilter
      """;
      
    2. Crie uma variável QueryDefinition chamada query passando a cadeia de caracteres sql como o único parâmetro de consulta. Além disso, use o método flexível WithParameter para aplicar o valor Tag-75 ao parâmetro @tagFilter.

      var query = new QueryDefinition(
          query: sql
      )
          .WithParameter("@tagFilter", "Tag-75");
      
    3. Use o método genérico GetItemQueryIterator<> e a variável query para criar um iterador que obtenha dados do Azure Cosmos DB. Armazene o iterador como uma variável chamada feed. Encapsule toda essa expressão em uma instrução using a fim de descartar o iterador posteriormente.

      using FeedIterator<Product> feed = container.GetItemQueryIterator<Product>(
          queryDefinition: query
      );
      
    4. Use um loop while para iterar por várias páginas de resultados e armazenar o valor em um List<> genérico chamado de resultados. Retorne os resultados como a saída do método RetrieveActiveProductsAsync.

      List<Product> results = new();
      
      while (feed.HasMoreResults)
      {
          FeedResponse<Product> response = await feed.ReadNextAsync();
          foreach (Product item in response)
          {
              results.Add(item);
          }
      }
      
      return results;
      
  13. Salve o arquivo Services/CosmosClient.cs.

    Dica

    Se não tiver certeza de que o código está correto, você poderá comparar o código-fonte com o código-fonte no GitHub.

Validar o aplicativo final

Por fim, você executará o aplicativo com recargas dinâmicas habilitadas. A execução do aplicativo validará se o código pode acessar dados da API para NoSQL.

  1. De volta ao terminal, execute o aplicativo.

    dotnet run
    
  2. A saída do comando de execução deve incluir uma lista de portas e URLs em que o aplicativo está em execução. Abra um novo navegador e acesse o aplicativo Web em execução. Observe todas as três páginas do aplicativo em execução. Cada página agora deve incluir dados dinâmicos do Azure Cosmos DB.

Limpar os recursos

Exclua os recursos criados neste artigo quando não forem mais necessários. Para fazer isso, navegue até a página da conta, selecione Data Explorer, selecione o banco de dados cosmicworks e, em seguida, selecione Excluir.

Próximas etapas

Agora que você criou seu primeiro aplicativo Web .NET usando o Azure Cosmos DB, você pode se aprofundar no SDK para importar mais dados, realizar consultas complexas e gerenciar seus recursos do Azure Cosmos DB for NoSQL.