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

APLICA-SE A: NoSQL

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

Neste tutorial, irá aprender a:

  • Criar e preencher um banco de dados e contêiner usando a API para NoSQL
  • Criar um aplicativo Web ASP.NET a partir de um modelo
  • Consultar dados do contêiner API para NoSQL usando o SDK do Azure para .NET

Pré-requisitos

Criar API para recursos NoSQL

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

  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 do campo CADEIA DE CONEXÃO PRIMÁRIA*. Esse valor será usado durante todo o tutorial.

    Captura de ecrã da página Chaves com os campos URI, Chave Primária e Cadeia de Ligação Principal 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 Contêiner na barra de comandos.

    Captura de ecrã da opção Novo Contentor na barra de comandos do Data Explorer.

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

    Definição 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 1000
    ID do contentor products
    Chave de partição /category/name

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

    Importante

    Neste tutorial, primeiro dimensionaremos o banco de dados até 1.000 RU/s em taxa de transferência compartilhada para maximizar o desempenho da migração de dados. Quando a migração de dados estiver concluída, reduziremos 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.

    Gorjeta

    Opcionalmente, você pode usar o Azure Cloud Shell aqui.

  9. Instale a v2 da cosmicworks ferramenta dotnet do NuGet.

    dotnet tool install --global cosmicworks  --version 2.*
    
  10. Use a cosmicworks ferramenta para preencher sua conta API para NoSQL com dados de produto de exemplo usando os valores de URI e CHAVE PRIMÁRIA que você registrou anteriormente neste laboratório. Esses valores registados serão utilizados para os endpoint parâmetros e key respectivamente.

    cosmicworks \
        --number-of-products 1759 \
        --number-of-employees 0 \
        --disable-hierarchical-partition-keys \
        --connection-string <nosql-connection-string>
    
  11. Observe a saída da ferramenta de linha de comando. Deve adicionar 1759 itens ao recipiente. A saída de exemplo incluída é truncada para brevidade.

    ── Parsing connection string ────────────────────────────────────────────────────────────────
    ╭─Connection string──────────────────────────────────────────────────────────────────────────╮
    │ AccountEndpoint=https://<account-name>.documents.azure.com:443/;AccountKey=<account-key>;  │
    ╰────────────────────────────────────────────────────────────────────────────────────────────╯
    ── Populating data ──────────────────────────────────────────────────────────────────────────
    ╭─Products configuration─────────────────────────────────────────────────────────────────────╮
    │ Database   cosmicworks                                                                     │
    │ Container  products                                                                        │
    │ Count      1,759                                                                           │
    ╰────────────────────────────────────────────────────────────────────────────────────────────╯
    ...
    [SEED]  00000000-0000-0000-0000-000000005951 | Road-650 Black, 60 - Bikes
    [SEED]  00000000-0000-0000-0000-000000005950 | Mountain-100 Silver, 42 - Bikes
    [SEED]  00000000-0000-0000-0000-000000005949 | Men's Bib-Shorts, L - Clothing
    [SEED]  00000000-0000-0000-0000-000000005948 | ML Mountain Front Wheel - Components
    [SEED]  00000000-0000-0000-0000-000000005947 | Mountain-500 Silver, 42 - Bikes
    
  12. Regresse à página Data Explorer da sua conta.

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

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

  14. Reduza a taxa de transferência de 1.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 ecrã da opção Guardar na barra de comandos do Data Explorer.

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

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

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

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

  18. No editor de consultas, adicione esta 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 ecrã da opção Executar Consulta na barra de comandos do Data Explorer.

  20. Os resultados devem ser uma matriz paginada de todos os itens no contêiner com um price valor inferior a 2.000 classificados do preço mais alto para o mais baixo. Por uma questão de brevidade, um subconjunto da saída está 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 esta consulta e, em seguida, selecione Executar consulta novamente para observar os resultados.

    SELECT
        p.name,
        p.category.name AS category,
        p.category.subCategory.name AS subcategory,
        p.tags
    FROM products p
    JOIN tag IN p.tags
    WHERE STRINGEQUALS(tag, "yellow", true)
    
  22. Os resultados devem ser uma matriz menor de itens filtrados para conter apenas itens que incluam pelo menos uma tag com um valor de nome de Tag-32. Novamente, um subconjunto da saída é incluído aqui para brevidade.

    [
      ...
      {
        "name": "HL Touring Frame - Yellow, 60",
        "category": "Components",
        "subcategory": "Touring Frames",
        "tags": [
          "Components",
          "Touring Frames",
          "Yellow",
          "60"
        ]
      },
      ...
    ]
    

Criar ASP.NET aplicação Web

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 extrai pacotes do NuGet de forma transparente. Você pode usar dotnet nuget list source para verificar as fontes do pacote. Se você não tiver o NuGet como fonte de pacote, use dotnet nuget add source para instalar o site como fonte.

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

  2. Instale o cosmicworks.template.web pacote de modelo de projeto 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. Crie e execute o projeto de aplicação Web.

    dotnet run
    
  5. Observe a saída do comando run. A saída deve incluir uma lista de portas e URLs onde o aplicativo está sendo executado.

    ...
    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 navegue até 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. Pare o aplicativo em execução encerrando o processo em execução.

    Gorjeta

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

  8. 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.

  9. Navegue até o arquivo Serviços/ICosmosService.cs e abra-o. Observe as implementações do método e RetrieveAllProductsAsync padrãoRetrieveActiveProductsAsync. Esses métodos criam uma lista estática de produtos para usar 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", category: new Category(name: "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: "bd43543e-024c-4cda-a852-e29202310214", category: new Category(name: "Components, Forks"), sku: "FK-5136", name: """ML Fork""", description: """The product called "ML Fork".""", price: 175.49000000000001m),
            ...
        };
    }
    
  10. Navegue até o arquivo Serviços/CosmosService.cs e abra-os. 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. Finalmente, navegue e abra os arquivos Modelos/Product.cs e Modelos/Category.cs . Observe os tipos de registro definidos em cada arquivo. Esses tipos serão usados em consultas ao longo deste tutorial.

    public record Product(
        string id,
        Category category,
        string sku,
        string name,
        string description,
        decimal price
    );
    
    public record Category(
        string name
    );
    

Consultar dados usando o SDK do .NET

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 API for NoSQL.

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

    dotnet add package Microsoft.Azure.Cosmos
    
  2. Compilar 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 Microsoft.Azure.Cosmos namespaces e Microsoft.Azure.Cosmos.Linq .

    using Microsoft.Azure.Cosmos;
    using Microsoft.Azure.Cosmos.Linq;
    
  5. Dentro da 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 CosmosService classe.

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

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

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

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

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

      var queryable = container.GetItemLinqQueryable<Product>();
      
    2. Construa uma consulta LINQ usando os Where métodos e OrderByDescending extension. Use o ToFeedIterator método extension para criar um iterador para obter dados do Azure Cosmos DB e armazenar 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 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 irá iterar até que a HasMoreResultsfeed propriedade da variável retorne false. Esse loop garantirá que você percorra todas as páginas de resultados do lado do servidor.

      while (feed.HasMoreResults)
      { }
      
    5. Dentro do loop while, chame assincronamente o feedReadNextAsync método da variável 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 à results lista.

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

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

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

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

      string sql = """
      SELECT
          p.id,
          p.name,
          p.category,
          p.sku,
          p.description,
          p.price
      FROM products p
      JOIN tag IN p.tags
      WHERE STRINGEQUALS(tag, @tagFilter, true)
      """;
      
    2. 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 red ao @tagFilter parâmetro.

      var query = new QueryDefinition(
          query: sql
      )
          .WithParameter("@tagFilter", "red");
      
    3. 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 FeedIterator<Product> feed = container.GetItemQueryIterator<Product>(
          queryDefinition: query
      );
      
    4. Use um loop while para iterar através de várias páginas de resultados e armazenar o valor em um genérico List<> nomeado resultados. Retorne os resultados como a saída do RetrieveActiveProductsAsync método.

      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 Serviços/CosmosClient.cs .

    Gorjeta

    Se você não tiver certeza de que seu código está correto, você pode verificar seu código-fonte em relação ao código de exemplo no GitHub.

Validar a candidatura final

Finalmente, você executará o aplicativo com recarregamentos quentes ativados . A execução do aplicativo validará que seu 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 run deve incluir uma lista de portas e URLs onde o aplicativo está sendo executado. Abra um novo navegador e navegue até 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.

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.

Próximos passos

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