Поделиться через


Руководство. Разработка консольного приложения .NET с помощью Azure Cosmos DB для NoSQL

ОБЛАСТЬ ПРИМЕНЕНИЯ: NoSQL

Пакет SDK Azure для .NET позволяет добавлять данные в контейнер API для NoSQL либо асинхронные отдельные операции, либо пакет транзакций. В этом руководстве описывается процесс создания консольного приложения .NET, которое добавляет несколько элементов в контейнер.

В этом руководстве описано следующее:

  • Создание базы данных с помощью API для NoSQL
  • Создание консольного приложения .NET и добавление пакета SDK Azure для .NET
  • Добавление отдельных элементов в контейнер API для NoSQL
  • Извлечение элементов из контейнера API для NoSQL
  • Создание транзакции с пакетными изменениями для контейнера API для NoSQL

Необходимые компоненты

Создание ресурсов API для NoSQL

Сначала создайте пустую базу данных в существующей учетной записи API для NoSQL. Вы создадите контейнер с помощью пакета SDK Azure для .NET позже.

  1. Перейдите к существующей учетной записи API для NoSQL в портал Azure.

  2. В меню ресурсов выберите "Ключи".

    Снимок экрана: страница учетной записи API для NoSQL. Параметр

  3. На странице "Ключи" просмотрите и запишите значение полей URI и PRIMARY KEY. Эти значения используются во всем руководстве.

    Снимок экрана: страница

  4. В меню ресурсов выберите Обозреватель данных.

    Снимок экрана: параметр обозревателя данных, выделенный в меню ресурсов.

  5. На странице обозревателя данных выберите параметр "Создать базу данных" на панели команд.

    Снимок экрана: параметр

  6. В диалоговом окне "Новая база данных" создайте контейнер со следующими параметрами:

    Значение
    Идентификатор базы данных cosmicworks
    Тип пропускной способности базы данных Вручную
    Объем пропускной способности базы данных 400

    Снимок экрана: диалоговое окно

  7. Нажмите кнопку "ОК ", чтобы создать базу данных.

Создание консольного приложения .NET

Теперь вы создадите консольное приложение .NET и импортируете пакет SDK Azure для .NET с помощью библиотеки Microsoft.Azure.Cosmos из NuGet.

  1. Откройте терминал в пустом каталоге.

  2. Создание консольного приложения с помощью встроенного console шаблона

    dotnet new console --langVersion preview
    
  3. Добавьте версию Microsoft.Azure.Cosmos пакета 3.31.1-preview из NuGet.

    dotnet add package Microsoft.Azure.Cosmos --version 3.31.1-preview
    
  4. Кроме того, добавьте предварительную версию System.CommandLine пакета из NuGet.

    dotnet add package System.CommandLine --prerelease
    
  5. Кроме того, добавьте Humanizer пакет из NuGet.

    dotnet add package Humanizer
    
  6. Создайте проект консольного приложения.

    dotnet build
    
  7. Откройте Visual Studio Code, используя текущую папку проекта в качестве рабочей области.

    Совет

    Вы можете запустить code . терминал, чтобы открыть Visual Studio Code и автоматически открыть рабочий каталог в качестве текущей рабочей области.

  8. Перейдите к файлу Program.cs и откройте его. Удалите весь существующий код в файле.

  9. Добавьте этот код в файл, чтобы использовать библиотеку System.CommandLine для синтаксического анализа командной строки для двух строк, передаваемых через --first параметры и --last параметры.

    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);
    

    Примечание.

    В этом руководстве не совсем важно понимать, как работает средство синтаксического анализа командной строки. Средство синтаксического анализа имеет четыре параметра, которые можно указать при запуске приложения. Три из этих параметров являются обязательными, так как они будут использоваться для создания полей идентификатора и ключа секции.

  10. На этом этапе проект не будет строиться, так как вы еще не определили статический CosmosHandler.ManageCustomerAsync метод.

  11. Сохраните файл Program.cs.

Добавление элементов в контейнер с помощью пакета SDK

Затем вы используете отдельные операции для добавления элементов в контейнер API для NoSQL. В этом разделе описано CosmosHandler.ManageCustomerAsync , как определить метод.

  1. Создайте файл CosmosHandler.cs .

  2. В файле CosmosHandler.cs добавьте новую директиву using для Humanizer пространств имен и Microsoft.Azure.Cosmos пространств имен.

    using Humanizer;
    using Microsoft.Azure.Cosmos;
    
  3. Создайте новый статический класс с именем CosmosHandler.

    public static class CosmosHandler
    { }
    
  4. Чтобы проверить работу этого приложения, создайте короткую реализацию статического ManageCustomerAsync метода для печати входных данных командной строки.

    public static async Task ManageCustomerAsync(string name, string email, string state, string country)
    {
        await Console.Out.WriteLineAsync($"Hello {name} of {state}, {country}!");
    }
    
  5. Сохраните файл CosmosHandler.cs .

  6. Вернитесь в терминал, запустите приложение.

    dotnet run -- --name 'Mica Pereira' --state 'Washington' --country 'United States'
    
  7. Выходные данные команды должны быть веселым приветствием.

    Hello Mica Pereira of Washington, United States!
    
  8. Вернитесь к файлу CosmosHandler.cs .

  9. В статическом классе CosmosHandler добавьте новый private static readonly член типа CosmosClient с именем _client.

    private static readonly CosmosClient _client;
    
  10. Создайте статический конструктор для CosmosHandler класса.

    static CosmosHandler()
    { }
    
  11. В конструкторе создайте новый экземпляр CosmosClient класса, передавая два строковых параметра со значениями URI и PRIMARY KEY , записанными ранее в лаборатории. Сохраните этот новый экземпляр в члене _client .

    static CosmosHandler()
    {
        _client = new CosmosClient(
            accountEndpoint: "<uri>", 
            authKeyOrResourceToken: "<primary-key>"
        );
    }
    
  12. Вернитесь в статический класс CosmosHandler , создайте новый асинхронный метод с именем GetContainerAsync , возвращающим объект Container.

    private static async Task<Container> GetContainerAsync()
    { }
    
  13. Чтобы выполнить следующие действия, добавьте этот код в GetContainerAsync метод.

    1. Получите базу данных и сохраните cosmicworks ее в переменной с именем database.

      Database database = _client.GetDatabase("cosmicworks");
      
    2. Создайте новый универсальный набор List<> string значений в списке путей иерархического ключа секции и сохраните его в переменной с именем keyPaths.

      List<string> keyPaths = new()
      {
          "/address/country",
          "/address/state"
      };
      
    3. Создайте новую ContainerProperties переменную с именем контейнера (customers) и списком путей ключа секции.

      ContainerProperties properties = new(
          id: "customers",
          partitionKeyPaths: keyPaths
      );
      
    4. CreateContainerIfNotExistsAsync Используйте метод для предоставления свойств контейнера и получения контейнера. Этот метод будет асинхронно создавать контейнер, если он еще не существует в базе данных. Возвращает результат в виде выходных GetContainerAsync данных метода.

      return await database.CreateContainerIfNotExistsAsync(
          containerProperties: properties
      );
      
  14. Удалите весь код в методе ManageCustomerAsync .

  15. Чтобы выполнить следующие действия, добавьте этот код в ManageCustomerAsync метод.

    1. Асинхронно вызовите GetContainerAsync метод и сохраните результат в переменной с именем container.

      Container container = await GetContainerAsync();
      
    2. Создайте новую переменную с именем id , которая использует Kebaberize метод из Humanizer для преобразования name параметра метода.

      string id = name.Kebaberize();
      

      Примечание.

      Метод Kebaberize заменит все пробелы дефисами и перевернет текст в нижний регистр.

    3. Создайте анонимный типизированный элемент с помощью namestateпараметров метода и country параметров метода и переменнойid. Сохраните элемент в виде переменной с именем customer.

      var customer = new {
          id = id,
          name = name,
          address = new {
              state = state,
              country = country
          }
      };
      
    4. Используйте асинхронный CreateItemAsync метод контейнера, чтобы создать новый элемент в контейнере и назначить метаданные ответа HTTP переменной с именем response.

      var response = await container.CreateItemAsync(customer);
      
    5. Напишите значения переменных response StatusCode и RequestCharge свойств в консоль. Также записывает значение переменной id .

      Console.WriteLine($"[{response.StatusCode}]\t{id}\t{response.RequestCharge} RUs");
      
  16. Сохраните файл CosmosHandler.cs .

  17. Вернитесь в терминал, снова запустите приложение.

    dotnet run -- --name 'Mica Pereira' --state 'Washington' --country 'United States'
    
  18. Выходные данные команды должны включать состояние и плату за запрос для операции.

    [Created]       mica-pereira    7.05 RUs
    

    Примечание.

    Плата за запрос может отличаться.

  19. Запустите приложение еще раз.

    dotnet run -- --name 'Mica Pereira' --state 'Washington' --country 'United States'
    
  20. На этот раз программа должна завершиться сбоем. Если прокрутить сообщение об ошибке, вы увидите, что сбой произошел из-за конфликта в уникальном идентификаторе элементов.

    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."
        ]
    );
    

Получение элемента с помощью пакета SDK

Теперь, когда вы создали первый элемент в контейнере, вы можете использовать тот же пакет SDK для получения элемента. Здесь вы будете запрашивать и указывать на чтение элемента, чтобы сравнить разницу в потреблении единиц запросов (ЕЗ).

  1. Вернитесь к файлу CosmosHandler.cs или откройте его.

  2. Удалите все строки кода из ManageCustomerAsync метода, кроме первых двух строк.

    public static async Task ManageCustomerAsync(string name, string email, string state, string country)
    {
        Container container = await GetContainerAsync();
    
        string id = name.Kebaberize();
    }
    
  3. Чтобы выполнить следующие действия, добавьте этот код в ManageCustomerAsync метод.

    1. Используйте асинхронный CreateItemAsync метод контейнера, чтобы создать новый элемент в контейнере и назначить метаданные ответа HTTP переменной с именем response.

      var response = await container.CreateItemAsync(customer);
      
    2. Создайте новую строку с именем sql SQL-запроса, чтобы получить элементы, в которых фильтр (@id) совпадает.

      string sql = @"
      SELECT
          *
      FROM customers c
      WHERE c.id = @id
      ";
      
    3. Создайте новую QueryDefinition переменную с именем query , передаваемую в строку в sql качестве единственного параметра запроса. Кроме того, используйте WithParameter метод жидкости для применения значения переменной id к параметру @id .

      var query = new QueryDefinition(
          query: sql
      )
          .WithParameter("@id", id);
      
    4. Используйте универсальный GetItemQueryIterator<> метод и переменную для создания итератора query , который получает данные из Azure Cosmos DB. Храните итератор в переменной с именем feed. Обтекайте все это выражение в инструкции using, чтобы удалить итератор позже.

      using var feed = container.GetItemQueryIterator<dynamic>(
          queryDefinition: query
      );
      
    5. Асинхронно вызовите ReadNextAsync метод переменной feed и сохраните результат в переменной с именем response.

      var response = await feed.ReadNextAsync();
      
    6. Напишите значения переменных response StatusCode и RequestCharge свойств в консоль. Также записывает значение переменной id .

      Console.WriteLine($"[{response.StatusCode}]\t{id}\t{response.RequestCharge} RUs");
      
  4. Сохраните файл CosmosHandler.cs .

  5. Вернитесь в терминал, запустите приложение, чтобы прочитать один элемент с помощью SQL-запроса.

    dotnet run -- --name 'Mica Pereira' --state 'Washington' --country 'United States'
    
  6. Выходные данные команды должны указывать на то, что запрос требует несколько единиц запроса (ЕЗ).

    [OK]    mica-pereira    2.82 RUs
    
  7. Вернитесь в файл CosmosHandler.cs , удалите все строки кода из ManageCustomerAsync метода еще раз, за исключением первых двух строк.

    public static async Task ManageCustomerAsync(string name, string email, string state, string country)
    {
        Container container = await GetContainerAsync();
    
        string id = name.Kebaberize();
    }
    
  8. Чтобы выполнить следующие действия, добавьте этот код в ManageCustomerAsync метод.

    1. Создайте новый экземпляр PartitionKeyBuilder , добавив state параметры в country качестве значения ключа секции с несколькими частью.

      var partitionKey = new PartitionKeyBuilder()
          .Add(country)
          .Add(state)
          .Build();
      
    2. Используйте метод контейнера, чтобы указывать на чтение элемента из контейнера ReadItemAsync<> с помощью id переменных и partitionKey переменных. Сохраните результат в переменной с именем response.

      var response = await container.ReadItemAsync<dynamic>(
          id: id, 
          partitionKey: partitionKey
      );
      
    3. Напишите значения переменных response StatusCode и RequestCharge свойств в консоль. Также записывает значение переменной id .

      Console.WriteLine($"[{response.StatusCode}]\t{id}\t{response.RequestCharge} RU");
      
  9. Сохраните файл CosmosHandler.cs еще раз.

  10. Вернитесь в терминал, запустите приложение еще раз, чтобы указать на чтение одного элемента.

    dotnet run -- --name 'Mica Pereira' --state 'Washington' --country 'United States'
    
  11. Выходные данные команды должны указывать на то, что запросу требуется один ЕЗ.

    [OK]    mica-pereira    1 RUs
    

Создание транзакции с помощью пакета SDK

Наконец, вы принимаете созданный элемент, считываете этот элемент и создаете другой связанный элемент в рамках одной транзакции с помощью пакета SDK Azure для .NET.

  1. Вернитесь к файлу CosmosHandler.cs или откройте его.

  2. Удалите эти строки кода из ManageCustomerAsync метода.

    var response = await container.ReadItemAsync<dynamic>(
        id: id, 
        partitionKey: partitionKey
    );
    
    Console.WriteLine($"[{response.StatusCode}]\t{id}\t{response.RequestCharge} RUs");
    
  3. Чтобы выполнить следующие действия, добавьте этот новый код в ManageCustomerAsync метод.

    1. Создайте анонимный типизированный элемент с помощью namestateпараметров метода и country параметров метода и переменнойid. Сохраните элемент в виде переменной с именем customerCart. Этот элемент представляет корзину покупок в режиме реального времени для клиента, который в настоящее время пуст.

      var customerCart = new {
          id = $"{Guid.NewGuid()}",
          customerId = id,
          items = new string[] {},
          address = new {
              state = state,
              country = country
          }
      };
      
    2. Создайте новый анонимный типизированный элемент с помощью namestateпараметров метода и country параметров метода и переменнойid. Сохраните элемент в виде переменной с именем customerCart. Этот элемент представляет сведения о доставке и контактных данных для клиента.

      var customerContactInfo = new {
          id = $"{id}-contact",
          customerId = id,
          email = email,
          location = $"{state}, {country}",
          address = new {
              state = state,
              country = country
          }
      };
      
    3. Создайте пакет с помощью метода контейнера CreateTransactionalBatch , передавающего partitionKey переменную. Сохраните пакет в переменной с именем batch. Используйте методы fluent для выполнения следующих действий:

      Способ Параметр
      ReadItem id строковая переменная
      CreateItem customerCart переменная анонимного типа
      CreateItem customerContactInfo переменная анонимного типа
      var batch = container.CreateTransactionalBatch(partitionKey)
          .ReadItem(id)
          .CreateItem(customerCart)
          .CreateItem(customerContactInfo);
      
    4. Используйте метод пакета ExecuteAsync для запуска транзакции. Сохраните результат в переменной с именем response.

      using var response = await batch.ExecuteAsync();
      
    5. Напишите значения переменных response StatusCode и RequestCharge свойств в консоль. Также записывает значение переменной id .

      Console.WriteLine($"[{response.StatusCode}]\t{response.RequestCharge} RUs");
      
  4. Сохраните файл CosmosHandler.cs еще раз.

  5. Вернитесь в терминал, запустите приложение еще раз, чтобы указать на чтение одного элемента.

    dotnet run -- --name 'Mica Pereira' --state 'Washington' --country 'United States'
    
  6. Выходные данные команды должны отображать единицы запроса, используемые для всей транзакции.

    [OK]    16.05 RUs
    

    Примечание.

    Плата за запрос может отличаться.

Проверка окончательных данных в обозревателе данных

Чтобы упаковать вещи, используйте обозреватель данных в портал Azure для просмотра данных и контейнера, созданного в этом руководстве.

  1. Перейдите к существующей учетной записи API для NoSQL в портал Azure.

  2. В меню ресурсов выберите Обозреватель данных.

    Снимок экрана: параметр обозревателя данных, выделенный в меню ресурсов.

  3. На странице обозревателя данных разверните cosmicworks базу данных и выберите customers контейнер.

    Снимок экрана: выбранный узел контейнера в узле базы данных.

  4. На панели команд выберите новый SQL-запрос.

    Снимок экрана: параметр

  5. В редакторе запросов обратите внимание на эту строку запроса SQL.

    SELECT * FROM c
    
  6. Выберите "Выполнить запрос" , чтобы запустить запрос и просмотреть результаты.

    Снимок экрана: параметр

  7. Результаты должны содержать массив JSON с тремя элементами, созданными в этом руководстве. Обратите внимание, что все элементы имеют одно и то же значение ключа иерархической секции, но уникальные поля идентификатора. Пример выходных данных, включенных, усечен для краткости.

    [
      {
        "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"
        },
        ...
      }
    ]
    

Очистка ресурсов

При отсутствии необходимости удалите базу данных, используемую в этом руководстве. Для этого перейдите на страницу учетной записи, выберите обозреватель данных, выберите cosmicworks базу данных и нажмите кнопку "Удалить".

Следующие шаги

Теперь, когда вы создали первое консольное приложение .NET с помощью Azure Cosmos DB, попробуйте следующее руководство, в котором вы обновите существующее веб-приложение для использования данных Azure Cosmos DB.