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
- Uma conta existente do Azure Cosmos DB for NoSQL.
- Se você tiver uma assinatura existente do Azure, crie uma nova conta.
- Nenhuma assinatura do Azure? Você pode experimentar o Azure Cosmos DB gratuitamente sem necessidade de cartão de crédito.
- Visual Studio Code
- .NET 6 (LTS) ou posterior
- Experiência na gravação de aplicativos C#.
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
.
Navegue até sua conta existente da API para NoSQL no portal do Azure.
No menu de recursos, selecione Chaves.
Na página Chaves, observe e registre o valor do campo PRIMARY CONNECTION STRING*. Este valor será usado ao longo do tutorial.
No menu de recursos, selecione Data Explorer.
Na página Data Explorer, selecione a opção Novo contêiner na barra de comandos.
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 1000
ID do contêiner products
Chave de partição /category/name
Importante
Neste tutorial, primeiro dimensionaremos o banco de dados em até 1.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.
Selecione OK para criar o banco de dados e o contêiner.
Abra um terminal para executar comandos para preencher o contêiner com dados.
Dica
Você também pode usar o Azure Cloud Shell aqui.
Instale a v2 da ferramenta dotnet
cosmicworks
do NuGet.dotnet tool install --global cosmicworks --version 2.*
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âmetrosendpoint
ekey
, respectivamente.cosmicworks \ --number-of-products 1759 \ --number-of-employees 0 \ --disable-hierarchical-partition-keys \ --connection-string <nosql-connection-string>
Observe a saída da ferramenta da linha de comando. Isso deve adicionar 1759 itens ao contêiner. A saída de exemplo incluída é truncada para fins de 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
Retorne à página Data Explorer da sua conta.
Na seção Dados, expanda o nó do banco de dados
cosmicworks
e selecione Dimensionar.Reduza a taxa de transferência de 1.000 para 400.
Na barra de comandos, selecione Salvar.
Na seção Dados, expanda e selecione o nó de contêiner dos produtos.
Na barra de comandos, selecione Nova consulta SQL.
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
Selecione Executar Consulta para executar a consulta e observar os resultados.
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 }, ...
Substitua o conteúdo do editor de consultas por essa consulta e 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)
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": "HL Touring Frame - Yellow, 60", "category": "Components", "subcategory": "Touring Frames", "tags": [ "Components", "Touring Frames", "Yellow", "60" ] }, ... ]
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.
Abra um terminal em um diretório vazio.
Instale o pacote de modelo de projeto
cosmicworks.template.web
do NuGet.dotnet new install cosmicworks.template.web
Crie um novo projeto de aplicativo Web usando o modelo recém-instalado
dotnet new cosmosdbnosql-webapp
.dotnet new cosmosdbnosql-webapp
Compile e execute o projeto do aplicativo Web.
dotnet run
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 ...
Abra um novo navegador e acesse o aplicativo Web em execução. Observe todas as três páginas do aplicativo em execução.
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.
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.Navegue até o arquivo Services/ICosmosService.cs e abra-o. Observe as implementações do método padrão
RetrieveActiveProductsAsync
eRetrieveAllProductsAsync
. 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", 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), ... }; }
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 { }
Por fim, navegue até e abra os arquivos Models/Product.cs e Models/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 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.
De volta ao terminal, adicione o pacote
Microsoft.Azure.Cosmos
do NuGet.dotnet add package Microsoft.Azure.Cosmos
Compile o projeto.
dotnet build
De volta ao Visual Studio Code, navegue novamente até o arquivo Services/CosmosService.cs.
Adicione uma nova diretiva using para os namespaces
Microsoft.Azure.Cosmos
eMicrosoft.Azure.Cosmos.Linq
.using Microsoft.Azure.Cosmos; using Microsoft.Azure.Cosmos.Linq;
Na classe CosmosService, adicione um novo
private readonly
membro do tipoCosmosClient
chamado_client
.private readonly CosmosClient _client;
Crie um novo construtor vazio para a classe
CosmosService
.public CosmosService() { }
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>" ); }
De volta à classe CosmosService, crie uma nova propriedade
private
do tipoContainer
chamadacontainer
. Defina o acessador get para retornar o banco de dadoscosmicworks
e o contêinerproducts
.private Container container { get => _client.GetDatabase("cosmicworks").GetContainer("products"); }
Crie um novo método assíncrono chamado
RetrieveAllProductsAsync
que retorna umIEnumerable<Product>
.public async Task<IEnumerable<Product>> RetrieveAllProductsAsync() { }
Para as próximas etapas, adicione esse código dentro do método
RetrieveAllProductsAsync
.Use o método genérico
GetItemLinqQueryable<>
para obter um objeto do tipoIQueryable<>
que você pode usar para construir uma LINQ (consulta integrada à linguagem). Armazene o objeto em uma variável chamadaqueryable
.var queryable = container.GetItemLinqQueryable<Product>();
Construa uma consulta LINQ usando os métodos de extensão
Where
eOrderByDescending
. Use o método de extensãoToFeedIterator
para criar um iterador para obter dados do Azure Cosmos DB e armazenar o iterador em uma variável chamadafeed
. 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();
Crie uma nova variável chamada
results
usando o tipo genéricoList<>
.List<Product> results = new();
Crie um loop while que será iterado até que a propriedade
HasMoreResults
da variávelfeed
retorne false. Esse loop garantirá que você faça loop em todas as páginas de resultados do lado do servidor.while (feed.HasMoreResults) { }
No loop while, chame de forma assíncrona o método
ReadNextAsync
da variávelfeed
e armazene o resultado em uma variável chamadaresponse
.while (feed.HasMoreResults) { var response = await feed.ReadNextAsync(); }
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); } }
Retorne a lista
results
como a saída do métodoRetrieveAllProductsAsync
.return results;
Crie um novo método assíncrono chamado
RetrieveActiveProductsAsync
que retorna umIEnumerable<Product>
.public async Task<IEnumerable<Product>> RetrieveActiveProductsAsync() { }
Para as próximas etapas, adicione esse código dentro do método
RetrieveActiveProductsAsync
.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.name, p.category, p.sku, p.description, p.price FROM products p JOIN tag IN p.tags WHERE STRINGEQUALS(tag, @tagFilter, true) """;
Crie uma variável
QueryDefinition
chamadaquery
passando a cadeia de caracteressql
como o único parâmetro de consulta. Além disso, use o método flexívelWithParameter
para aplicar o valorred
ao parâmetro@tagFilter
.var query = new QueryDefinition( query: sql ) .WithParameter("@tagFilter", "red");
Use o método genérico
GetItemQueryIterator<>
e a variávelquery
para criar um iterador que obtenha dados do Azure Cosmos DB. Armazene o iterador como uma variável chamadafeed
. 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 );
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étodoRetrieveActiveProductsAsync
.List<Product> results = new(); while (feed.HasMoreResults) { FeedResponse<Product> response = await feed.ReadNextAsync(); foreach (Product item in response) { results.Add(item); } } return results;
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.
De volta ao terminal, execute o aplicativo.
dotnet run
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.