Tutoriel : Développement d’une application console .NET avec Azure Cosmos DB for NoSQL
S’APPLIQUE À : NoSQL
Le Kit de développement logiciel (SDK) Azure pour .NET vous permet d’ajouter des données à un conteneur API for NoSQL avec des opérations individuelles asynchrones ou un lot transactionnel. Ce tutoriel décrit le processus de création d’une application console .NET qui ajoute plusieurs éléments à un conteneur.
Dans ce tutoriel, vous allez apprendre à :
- Créer une base de données à l’aide d’API for NoSQL
- Créer une application console .NET et ajouter le kit SDK Azure pour .NET
- Ajouter des éléments individuellement dans un conteneur API for NoSQL
- Récupérer efficacement des éléments d’un conteneur API for NoSQL
- Créer une transaction avec des modifications par lot pour le conteneur API for NoSQL
Prérequis
- Un compte Azure Cosmos DB for NoSQL déjà créé :
- Si vous disposez d’un abonnement Azure, créez un compte.
- Vous ne possédez pas d’abonnement Azure ? Vous pouvez essayer Azure Cosmos DB gratuitement sans carte de crédit.
- Visual Studio Code
- .NET 8 ou ultérieur
- Expérience dans l’écriture d’applications C#
Création de ressources API for NoSQL
Tout d’abord, créez une base de données vide dans le compte API for NoSQL. Vous créez un conteneur en utilisant le Kit de développement logiciel (SDK) Azure pour .NET plus tard.
Accédez à votre compte API for NoSQL sur le Portail Azure.
Dans le menu des ressources, sélectionnez Clés.
Sur la page Clés, observez et enregistrez la valeur des champs URI et CLÉ PRIMAIRE. Ces valeurs sont utilisées tout au long du tutoriel.
Dans le menu de la ressource, sélectionnez Explorateur de données.
Sur la page Data Explorer, sélectionnez l’option Nouvelle base de données dans la barre de commandes.
Dans la boîte de dialogue Nouvelle base de données, créez un conteneur en indiquant les paramètres suivants :
Valeur ID de base de données cosmicworks
Type de débit de la base de données Manuel Valeur du débit de la base de données 400
Sélectionnez OK pour créer la base de données.
Création d’une application console .NET
À présent, vous créez une application console .NET et vous importez le Kit de développement logiciel (SDK) Azure pour .NET en utilisant la bibliothèque Microsoft.Azure.Cosmos
de NuGet.
Ouvrez un terminal dans un répertoire vide.
Créez une application console à l’aide du modèle intégré
console
.dotnet new console --langVersion preview
Ajoutez la version 3.31.1-preview du package
Microsoft.Azure.Cosmos
à partir de NuGet.dotnet add package Microsoft.Azure.Cosmos --version 3.31.1-preview
Ajoutez également la version prerelease du package
System.CommandLine
à partir de NuGet.dotnet add package System.CommandLine --prerelease
Ajoutez également le package
Humanizer
à partir de NuGet.dotnet add package Humanizer
Générez le projet de l’application console.
dotnet build
Ouvrez Visual Studio Code en utilisant le dossier de projet actuel comme espace de travail.
Conseil
Vous pouvez exécuter
code .
dans le terminal pour lancer Visual Studio Code et ouvrir automatiquement le répertoire de travail comme espace de travail actif.Accédez au fichier Program.cs et ouvrez-le. Supprimez tout le code existant dans le fichier.
Ajoutez ce code au fichier de façon à utiliser la bibliothèque System.CommandLine pour analyser deux chaînes transmises avec les options
--first
et--last
dans la ligne de commande.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);
Notes
Dans le cadre ce tutoriel, il n’est pas très important de comprendre le fonctionnement de l’analyseur de ligne de commande. L’analyseur comporte quatre options qui peuvent être spécifiées lorsque l’application est en cours d’exécution. Trois d’entre elles sont requises, car elles seront utilisées pour construire les champs ID et Clé de partition.
Le projet n’est pas encore généré, car vous n’avez pas encore défini la méthode statique
CosmosHandler.ManageCustomerAsync
.Enregistrez le fichier Program.cs.
Ajout d’éléments à un conteneur à l’aide du kit SDK
Ensuite, vous utilisez des opérations individuelles pour ajouter des éléments dans l’API pour le conteneur NoSQL. Dans cette section, vous définissez la méthode CosmosHandler.ManageCustomerAsync
.
Créez un fichier CosmosHandler.cs.
Dans le fichier CosmosHandler.cs, ajoutez une nouvelle directive using pour les espaces de noms
Humanizer
etMicrosoft.Azure.Cosmos
.using Humanizer; using Microsoft.Azure.Cosmos;
Créez une classe statique nommée
CosmosHandler
.public static class CosmosHandler { }
Juste pour vérifier que cette application fonctionne, créez une courte implémentation de la méthode statique
ManageCustomerAsync
qui affiche l’entrée de la ligne de commande.public static async Task ManageCustomerAsync(string name, string email, string state, string country) { await Console.Out.WriteLineAsync($"Hello {name} of {state}, {country}!"); }
Enregistrez le fichier CosmosHandler.cs.
De retour dans le terminal, exécutez l’application.
dotnet run -- --name 'Mica Pereira' --state 'Washington' --country 'United States'
La sortie de la commande correspond en principe à un message d’accueil amusant.
Hello Mica Pereira of Washington, United States!
Revenez au fichier CosmosHandler.cs.
Dans la classe statique CosmosHandler, ajoutez un nouveau membre
private static readonly
de typeCosmosClient
et nommé_client
.private static readonly CosmosClient _client;
Créez un constructeur statique pour la classe
CosmosHandler
.static CosmosHandler() { }
Dans le constructeur, créez une instance de la classe
CosmosClient
en transmettant deux paramètres de chaîne avec les valeurs URI et CLÉ PRIMAIRE que vous avez enregistrées dans le labo. Stockez cette nouvelle instance dans le membre_client
.static CosmosHandler() { _client = new CosmosClient( accountEndpoint: "<uri>", authKeyOrResourceToken: "<primary-key>" ); }
De retour dans la classe statique CosmosHandler, créez une méthode asynchrone nommée
GetContainerAsync
qui retourne unContainer
.private static async Task<Container> GetContainerAsync() { }
Pour les étapes suivantes, ajoutez ce code dans la méthode
GetContainerAsync
.Récupérez la base de données
cosmicworks
et stockez-la dans une variable nomméedatabase
.Database database = _client.GetDatabase("cosmicworks");
Créez une
List<>
générique de valeursstring
dans une liste de chemins de clés de partition hiérarchiques et stockez-la dans une variable nomméekeyPaths
.List<string> keyPaths = new() { "/address/country", "/address/state" };
Créez une variable
ContainerProperties
comportant le nom du conteneur (customers
) et la liste des chemins de clés de partition.ContainerProperties properties = new( id: "customers", partitionKeyPaths: keyPaths );
Utilisez la méthode
CreateContainerIfNotExistsAsync
pour fournir les propriétés du conteneur et récupérer ce dernier. Comme l’indique son nom, cette méthode crée le conteneur de manière asynchrone s’il n’existe pas déjà dans la base de données. Elle retourne le résultat en sortie de la méthodeGetContainerAsync
.return await database.CreateContainerIfNotExistsAsync( containerProperties: properties );
Supprimez tout le code de la méthode
ManageCustomerAsync
.Pour les étapes suivantes, ajoutez ce code dans la méthode
ManageCustomerAsync
.Appelez de façon asynchrone la méthode
GetContainerAsync
et stockez le résultat dans une variable nomméecontainer
.Container container = await GetContainerAsync();
Créez une variable nommée
id
qui utilise la méthodeKebaberize
de Humanizer pour transformer le paramètre de méthodename
.string id = name.Kebaberize();
Notes
La méthode
Kebaberize
remplace tous les espaces par des traits d’union et convertit le texte en minuscules.Créez un élément typé anonyme à l’aide des paramètres de méthode
name
,state
etcountry
, et de la variableid
. Stockez l’élément sous la forme d’une variable nomméecustomer
.var customer = new { id = id, name = name, address = new { state = state, country = country } };
Utilisez la méthode asynchrone
CreateItemAsync
du conteneur pour créer un élément dans le conteneur et affecter les métadonnées de réponse HTTP à une variable nomméeresponse
.var response = await container.CreateItemAsync(customer);
Écrivez les valeurs des propriétés
StatusCode
etRequestCharge
de la variableresponse
dans la console. Écrivez également la valeur de la variableid
.Console.WriteLine($"[{response.StatusCode}]\t{id}\t{response.RequestCharge} RUs");
Enregistrez le fichier CosmosHandler.cs.
De retour dans le terminal, réexécutez l’application.
dotnet run -- --name 'Mica Pereira' --state 'Washington' --country 'United States'
La sortie de la commande correspond en principe à un état et aux frais de demande de l’opération.
[Created] mica-pereira 7.05 RUs
Notes
Vos frais de demande peuvent différer.
Exécutez à nouveau l’application.
dotnet run -- --name 'Mica Pereira' --state 'Washington' --country 'United States'
Cette fois, le programme devrait se bloquer. Si vous faites défiler le message d’erreur, vous voyez que l’incident s’est produit en raison d’un conflit dans l’identificateur unique des éléments.
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." ] );
Récupération d’un élément à l’aide du kit SDK
Maintenant que vous avez créé votre premier élément dans le conteneur, vous pouvez utiliser le même kit SDK pour récupérer cet élément. Vous allez interroger et lire (point read) l’élément pour examiner la différence de consommation d’unités de requête (RU).
Revenez au fichier CosmosHandler.cs ou ouvrez-le.
Supprimez toutes les lignes de code de la méthode
ManageCustomerAsync
, à l’exception des deux premières.public static async Task ManageCustomerAsync(string name, string email, string state, string country) { Container container = await GetContainerAsync(); string id = name.Kebaberize(); }
Pour les étapes suivantes, ajoutez ce code dans la méthode
ManageCustomerAsync
.Utilisez la méthode asynchrone
CreateItemAsync
du conteneur pour créer un élément dans le conteneur et affecter les métadonnées de réponse HTTP à une variable nomméeresponse
.var response = await container.CreateItemAsync(customer);
Créez une chaîne nommée
sql
qui contient une requête SQL permettant de récupérer les éléments correspondant à un filtre (@id
).string sql = @" SELECT * FROM customers c WHERE c.id = @id ";
Créez une variable
QueryDefinition
nomméequery
et transmettant la chaînesql
comme seul paramètre de requête. Utilisez également la méthode FluidWithParameter
pour appliquer la valeur de la variableid
au paramètre@id
.var query = new QueryDefinition( query: sql ) .WithParameter("@id", id);
Utilisez la méthode générique
GetItemQueryIterator<>
et la variablequery
pour créer un itérateur qui récupère des données à partir d’Azure Cosmos DB. Stockez l’itérateur dans une variable nomméefeed
. Encapsulez l’expression entière dans une instruction using pour pouvoir supprimer l’itérateur ultérieurement.using var feed = container.GetItemQueryIterator<dynamic>( queryDefinition: query );
Appelez de façon asynchrone la méthode
ReadNextAsync
de la variablefeed
et stockez le résultat dans une variable nomméeresponse
.var response = await feed.ReadNextAsync();
Écrivez les valeurs des propriétés
StatusCode
etRequestCharge
de la variableresponse
dans la console. Écrivez également la valeur de la variableid
.Console.WriteLine($"[{response.StatusCode}]\t{id}\t{response.RequestCharge} RUs");
Enregistrez le fichier CosmosHandler.cs.
De retour dans le terminal, exécutez l’application pour lire l’élément à l’aide d’une requête SQL.
dotnet run -- --name 'Mica Pereira' --state 'Washington' --country 'United States'
La sortie de la commande indique en principe que la requête a consommé plusieurs unités de requête (RU).
[OK] mica-pereira 2.82 RUs
De retour dans le fichier CosmosHandler.cs, supprimez à nouveau toutes les lignes de code de la méthode
ManageCustomerAsync
, à l’exception des deux premières.public static async Task ManageCustomerAsync(string name, string email, string state, string country) { Container container = await GetContainerAsync(); string id = name.Kebaberize(); }
Pour les étapes suivantes, ajoutez ce code dans la méthode
ManageCustomerAsync
.Créez une instance de
PartitionKeyBuilder
en ajoutant les paramètresstate
etcountry
comme valeur de clé de partition en plusieurs parties.var partitionKey = new PartitionKeyBuilder() .Add(country) .Add(state) .Build();
Utilisez la méthode du conteneur
ReadItemAsync<>
pour lire (point read) l’élément du conteneur à l’aide des variablesid
etpartitionKey
. Enregistrez le résultat dans une variable nomméeresponse
.var response = await container.ReadItemAsync<dynamic>( id: id, partitionKey: partitionKey );
Écrivez les valeurs des propriétés
StatusCode
etRequestCharge
de la variableresponse
dans la console. Écrivez également la valeur de la variableid
.Console.WriteLine($"[{response.StatusCode}]\t{id}\t{response.RequestCharge} RU");
Enregistrez à nouveau le fichier CosmosHandler.cs.
De retour dans le terminal, exécutez à nouveau l’application pour lire (point read) l’élément.
dotnet run -- --name 'Mica Pereira' --state 'Washington' --country 'United States'
La sortie de la commande indique en principe que la requête a consommé une seule RU.
[OK] mica-pereira 1 RUs
Création d’une transaction à l’aide du kit SDK
Enfin, vous prenez l’élément que vous avez créé, vous lisez cet élément et vous créez un autre élément associé dans le cadre d’une même transaction en utilisant le Kit de développement logiciel (SDK) Azure pour .NET.
Revenez au fichier CosmosHandler.cs ou ouvrez-le.
Supprimez ces lignes de code de la méthode
ManageCustomerAsync
.var response = await container.ReadItemAsync<dynamic>( id: id, partitionKey: partitionKey ); Console.WriteLine($"[{response.StatusCode}]\t{id}\t{response.RequestCharge} RUs");
Pour les étapes suivantes, ajoutez ce nouveau code dans la méthode
ManageCustomerAsync
.Créez un élément typé anonyme à l’aide des paramètres de méthode
name
,state
etcountry
, et de la variableid
. Stockez l’élément sous la forme d’une variable nomméecustomerCart
. Cet élément représente le panier d’achat en temps réel du client, qui est actuellement vide.var customerCart = new { id = $"{Guid.NewGuid()}", customerId = id, items = new string[] {}, address = new { state = state, country = country } };
Créez un autre élément typé anonyme à l’aide des paramètres de méthode
name
,state
etcountry
, et de la variableid
. Stockez l’élément sous la forme d’une variable nomméecustomerCart
. Cet élément représente les informations d’expédition et de contact du client.var customerContactInfo = new { id = $"{id}-contact", customerId = id, email = email, location = $"{state}, {country}", address = new { state = state, country = country } };
Créez un lot à l’aide de la méthode
CreateTransactionalBatch
du conteneur en transmettant la variablepartitionKey
. Stockez le lot dans une variable nomméebatch
. Utilisez les méthodes Fluent pour effectuer les actions suivantes :Méthode Paramètre ReadItem
Variable de chaîne id
CreateItem
Variable de type anonyme customerCart
CreateItem
Variable de type anonyme customerContactInfo
var batch = container.CreateTransactionalBatch(partitionKey) .ReadItem(id) .CreateItem(customerCart) .CreateItem(customerContactInfo);
Utilisez la méthode
ExecuteAsync
du lot pour lancer la transaction. Enregistrez le résultat dans une variable nomméeresponse
.using var response = await batch.ExecuteAsync();
Écrivez les valeurs des propriétés
StatusCode
etRequestCharge
de la variableresponse
dans la console. Écrivez également la valeur de la variableid
.Console.WriteLine($"[{response.StatusCode}]\t{response.RequestCharge} RUs");
Enregistrez à nouveau le fichier CosmosHandler.cs.
De retour dans le terminal, exécutez à nouveau l’application pour lire (point read) l’élément.
dotnet run -- --name 'Mica Pereira' --state 'Washington' --country 'United States'
La sortie de la commande affiche en principe les unités de requête utilisées pour l’ensemble de la transaction.
[OK] 16.05 RUs
Notes
Vos frais de demande peuvent différer.
Validation des données finales dans Data Explorer
Pour conclure, vous utilisez l’Explorateur de données dans le portail Azure pour visualiser les données et le conteneur que vous avez créés dans ce tutoriel.
Accédez à votre compte API for NoSQL sur le Portail Azure.
Dans le menu de la ressource, sélectionnez Explorateur de données.
Sur la page Data Explorer, développez la base de données
cosmicworks
, puis sélectionnez le conteneurcustomers
.Dans la barre de commandes, sélectionnez Nouvelle requête SQL.
Dans l’éditeur de requête, observez cette chaîne de requête SQL.
SELECT * FROM c
Sélectionnez Exécuter la requête pour exécuter la requête, puis observez les résultats.
Les résultats correspondent en principe à un tableau JSON avec trois éléments créés dans ce tutoriel. Notez que tous les éléments possèdent la même valeur de clé de partition hiérarchique, mais des champs d’ID uniques. L’exemple de sortie inclus est tronqué par souci de concision.
[ { "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" }, ... } ]
Nettoyer les ressources
Quand vous n’en avez plus besoin, supprimez les bases de données utilisées dans ce tutoriel. Pour ce faire, accédez à la page du compte, sélectionnez Data Explorer, la base de données cosmicworks
, puis Supprimer.