Partage via


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

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.

  1. Accédez à votre compte API for NoSQL sur le Portail Azure.

  2. Dans le menu des ressources, sélectionnez Clés.

    Capture d’écran de la page d’un compte API for NoSQL, avec l’option Clés encadrée dans le menu des ressources.

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

    Capture d’écran de la page Clés avec les champs URI et CLÉ PRIMAIRE encadrés.

  4. Dans le menu de la ressource, sélectionnez Explorateur de données.

    Capture d’écran de l’option Data Explorer encadrée dans le menu des ressources.

  5. Sur la page Data Explorer, sélectionnez l’option Nouvelle base de données dans la barre de commandes.

    Capture d’écran de l’option Nouvelle base de données dans la barre de commandes Data Explorer.

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

    Capture d’écran de la boîte de dialogue Nouvelle base de données dans Data Explorer, comportant différentes valeurs dans chaque champ.

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

  1. Ouvrez un terminal dans un répertoire vide.

  2. Créez une application console à l’aide du modèle intégré console.

    dotnet new console --langVersion preview
    
  3. 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
    
  4. Ajoutez également la version prerelease du package System.CommandLine à partir de NuGet.

    dotnet add package System.CommandLine --prerelease
    
  5. Ajoutez également le package Humanizer à partir de NuGet.

    dotnet add package Humanizer
    
  6. Générez le projet de l’application console.

    dotnet build
    
  7. 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.

  8. Accédez au fichier Program.cs et ouvrez-le. Supprimez tout le code existant dans le fichier.

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

  10. Le projet n’est pas encore généré, car vous n’avez pas encore défini la méthode statique CosmosHandler.ManageCustomerAsync.

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

  1. Créez un fichier CosmosHandler.cs.

  2. Dans le fichier CosmosHandler.cs, ajoutez une nouvelle directive using pour les espaces de noms Humanizer et Microsoft.Azure.Cosmos.

    using Humanizer;
    using Microsoft.Azure.Cosmos;
    
  3. Créez une classe statique nommée CosmosHandler.

    public static class CosmosHandler
    { }
    
  4. 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}!");
    }
    
  5. Enregistrez le fichier CosmosHandler.cs.

  6. De retour dans le terminal, exécutez l’application.

    dotnet run -- --name 'Mica Pereira' --state 'Washington' --country 'United States'
    
  7. La sortie de la commande correspond en principe à un message d’accueil amusant.

    Hello Mica Pereira of Washington, United States!
    
  8. Revenez au fichier CosmosHandler.cs.

  9. Dans la classe statique CosmosHandler, ajoutez un nouveau membre private static readonly de type CosmosClient et nommé _client.

    private static readonly CosmosClient _client;
    
  10. Créez un constructeur statique pour la classe CosmosHandler.

    static CosmosHandler()
    { }
    
  11. 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>"
        );
    }
    
  12. De retour dans la classe statique CosmosHandler, créez une méthode asynchrone nommée GetContainerAsync qui retourne un Container.

    private static async Task<Container> GetContainerAsync()
    { }
    
  13. Pour les étapes suivantes, ajoutez ce code dans la méthode GetContainerAsync.

    1. Récupérez la base de données cosmicworks et stockez-la dans une variable nommée database.

      Database database = _client.GetDatabase("cosmicworks");
      
    2. Créez une List<> générique de valeurs string dans une liste de chemins de clés de partition hiérarchiques et stockez-la dans une variable nommée keyPaths.

      List<string> keyPaths = new()
      {
          "/address/country",
          "/address/state"
      };
      
    3. 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
      );
      
    4. 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éthode GetContainerAsync.

      return await database.CreateContainerIfNotExistsAsync(
          containerProperties: properties
      );
      
  14. Supprimez tout le code de la méthode ManageCustomerAsync.

  15. Pour les étapes suivantes, ajoutez ce code dans la méthode ManageCustomerAsync.

    1. Appelez de façon asynchrone la méthode GetContainerAsync et stockez le résultat dans une variable nommée container.

      Container container = await GetContainerAsync();
      
    2. Créez une variable nommée id qui utilise la méthode Kebaberize de Humanizer pour transformer le paramètre de méthode name.

      string id = name.Kebaberize();
      

      Notes

      La méthode Kebaberize remplace tous les espaces par des traits d’union et convertit le texte en minuscules.

    3. Créez un élément typé anonyme à l’aide des paramètres de méthode name, state et country, et de la variable id. Stockez l’élément sous la forme d’une variable nommée customer.

      var customer = new {
          id = id,
          name = name,
          address = new {
              state = state,
              country = country
          }
      };
      
    4. 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ée response.

      var response = await container.CreateItemAsync(customer);
      
    5. Écrivez les valeurs des propriétés StatusCode et RequestCharge de la variable response dans la console. Écrivez également la valeur de la variable id.

      Console.WriteLine($"[{response.StatusCode}]\t{id}\t{response.RequestCharge} RUs");
      
  16. Enregistrez le fichier CosmosHandler.cs.

  17. De retour dans le terminal, réexécutez l’application.

    dotnet run -- --name 'Mica Pereira' --state 'Washington' --country 'United States'
    
  18. 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.

  19. Exécutez à nouveau l’application.

    dotnet run -- --name 'Mica Pereira' --state 'Washington' --country 'United States'
    
  20. 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).

  1. Revenez au fichier CosmosHandler.cs ou ouvrez-le.

  2. 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();
    }
    
  3. Pour les étapes suivantes, ajoutez ce code dans la méthode ManageCustomerAsync.

    1. 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ée response.

      var response = await container.CreateItemAsync(customer);
      
    2. 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
      ";
      
    3. Créez une variable QueryDefinition nommée query et transmettant la chaîne sql comme seul paramètre de requête. Utilisez également la méthode Fluid WithParameter pour appliquer la valeur de la variable id au paramètre @id.

      var query = new QueryDefinition(
          query: sql
      )
          .WithParameter("@id", id);
      
    4. Utilisez la méthode générique GetItemQueryIterator<> et la variable query 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ée feed. 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
      );
      
    5. Appelez de façon asynchrone la méthode ReadNextAsync de la variable feed et stockez le résultat dans une variable nommée response.

      var response = await feed.ReadNextAsync();
      
    6. Écrivez les valeurs des propriétés StatusCode et RequestCharge de la variable response dans la console. Écrivez également la valeur de la variable id.

      Console.WriteLine($"[{response.StatusCode}]\t{id}\t{response.RequestCharge} RUs");
      
  4. Enregistrez le fichier CosmosHandler.cs.

  5. 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'
    
  6. 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
    
  7. 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();
    }
    
  8. Pour les étapes suivantes, ajoutez ce code dans la méthode ManageCustomerAsync.

    1. Créez une instance de PartitionKeyBuilder en ajoutant les paramètres state et country comme valeur de clé de partition en plusieurs parties.

      var partitionKey = new PartitionKeyBuilder()
          .Add(country)
          .Add(state)
          .Build();
      
    2. Utilisez la méthode du conteneur ReadItemAsync<> pour lire (point read) l’élément du conteneur à l’aide des variables id et partitionKey. Enregistrez le résultat dans une variable nommée response.

      var response = await container.ReadItemAsync<dynamic>(
          id: id, 
          partitionKey: partitionKey
      );
      
    3. Écrivez les valeurs des propriétés StatusCode et RequestCharge de la variable response dans la console. Écrivez également la valeur de la variable id.

      Console.WriteLine($"[{response.StatusCode}]\t{id}\t{response.RequestCharge} RU");
      
  9. Enregistrez à nouveau le fichier CosmosHandler.cs.

  10. 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'
    
  11. 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.

  1. Revenez au fichier CosmosHandler.cs ou ouvrez-le.

  2. 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");
    
  3. Pour les étapes suivantes, ajoutez ce nouveau code dans la méthode ManageCustomerAsync.

    1. Créez un élément typé anonyme à l’aide des paramètres de méthode name, state et country, et de la variable id. Stockez l’élément sous la forme d’une variable nommée customerCart. 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
          }
      };
      
    2. Créez un autre élément typé anonyme à l’aide des paramètres de méthode name, state et country, et de la variable id. Stockez l’élément sous la forme d’une variable nommée customerCart. 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
          }
      };
      
    3. Créez un lot à l’aide de la méthode CreateTransactionalBatch du conteneur en transmettant la variable partitionKey. Stockez le lot dans une variable nommée batch. 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);
      
    4. Utilisez la méthode ExecuteAsync du lot pour lancer la transaction. Enregistrez le résultat dans une variable nommée response.

      using var response = await batch.ExecuteAsync();
      
    5. Écrivez les valeurs des propriétés StatusCode et RequestCharge de la variable response dans la console. Écrivez également la valeur de la variable id.

      Console.WriteLine($"[{response.StatusCode}]\t{response.RequestCharge} RUs");
      
  4. Enregistrez à nouveau le fichier CosmosHandler.cs.

  5. 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'
    
  6. 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.

  1. Accédez à votre compte API for NoSQL sur le Portail Azure.

  2. Dans le menu de la ressource, sélectionnez Explorateur de données.

    Capture d’écran de l’option Data Explorer encadrée dans le menu des ressources.

  3. Sur la page Data Explorer, développez la base de données cosmicworks, puis sélectionnez le conteneur customers.

    Capture d’écran du nœud de conteneur sélectionné dans le nœud de base de données.

  4. Dans la barre de commandes, sélectionnez Nouvelle requête SQL.

    Capture d’écran de l’option Nouvelle requête SQL dans la barre de commandes Data Explorer.

  5. Dans l’éditeur de requête, observez cette chaîne de requête SQL.

    SELECT * FROM c
    
  6. Sélectionnez Exécuter la requête pour exécuter la requête, puis observez les résultats.

    Capture d’écran de l’option « Exécuter la requête » dans la barre de commandes de l’Explorateur de données.

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