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

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

Пакет SDK Azure для .NET позволяет запрашивать данные в контейнере API для NoSQL с помощью LINQ в C# или строки запроса SQL. В этом руководстве описывается процесс обновления существующего веб-приложения ASP.NET, использующего заполнители для запроса из API.

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

  • Создание и заполнение базы данных и контейнера с помощью API для NoSQL
  • Создание веб-приложения ASP.NET на основе шаблона
  • Запрос данных из контейнера API для NoSQL с помощью пакета SDK Azure для .NET

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

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

Сначала вы создадите базу данных и контейнер в существующей учетной записи API для NoSQL. Затем вы заполните эту учетную запись данными cosmicworks с помощью средства dotnet.

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

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

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

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

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

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

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

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

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

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

    Параметр Значение
    Идентификатор базы данных cosmicworks
    Тип пропускной способности базы данных Вручную
    Объем пропускной способности базы данных 1000
    Идентификатор контейнера products
    Ключ секции /category/name

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

    Внимание

    В этом руководстве мы сначала масштабируем базу данных до 1000 ЕЗ/с в общей пропускной способности, чтобы повысить производительность миграции данных. После завершения миграции данных мы масштабируем до 400 ЕЗ/с подготовленной пропускной способности.

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

  8. Откройте терминал для выполнения команд, чтобы заполнить контейнер данными.

    Совет

    Вы также можете использовать Azure Cloud Shell здесь.

  9. Установите версию cosmicworks 2 средства dotnet из NuGet.

    dotnet tool install --global cosmicworks  --version 2.*
    
  10. cosmicworks Используйте средство для заполнения учетной записи API для NoSQL с примерами данных продукта с помощью URI и значений PRIMARY KEY, записанных ранее в этой лаборатории. Эти записанные значения будут использоваться для endpoint параметров и key параметров соответственно.

    cosmicworks \
        --number-of-products 1759 \
        --number-of-employees 0 \
        --disable-hierarchical-partition-keys \
        --connection-string <nosql-connection-string>
    
  11. Просмотрите выходные данные из средства командной строки. Он должен добавить в контейнер 1759 элементов. Пример выходных данных, включенных, усечен для краткости.

    ── 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. Вернитесь на страницу "Данные Обозреватель" для учетной записи.

  13. В разделе "Данные" разверните cosmicworks узел базы данных и выберите "Масштаб".

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

  14. Уменьшите пропускную способность от 1000 до 400.

    Снимок экрана: параметры пропускной способности для базы данных сократились до 400 ЕЗ/с.

  15. В командной строке выберите Сохранить.

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

  16. В разделе "Данные" разверните узел контейнера продуктов и выберите его.

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

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

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

  18. В редакторе запросов добавьте эту строку запроса SQL.

    SELECT
      p.sku,
      p.price
    FROM products p
    WHERE p.price < 2000
    ORDER BY p.price DESC
    
  19. Выберите "Выполнить запрос" , чтобы запустить запрос и просмотреть результаты.

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

  20. Результаты должны быть массивом с разбивкой на страницы всех элементов в контейнере со price значением, которое меньше 2000 отсортировано от максимальной цены до наименьшей. Для краткости ниже приведено подмножество выходных данных.

    [
      {
        "sku": "BK-R79Y-48",
        "price": 1700.99
      },
      ...
      {
        "sku": "FR-M94B-46",
        "price": 1349.6
      },
    ...
    
  21. Замените содержимое редактора запросов этим запросом, а затем снова нажмите кнопку "Выполнить запрос ", чтобы просмотреть результаты.

    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. Результаты должны быть меньшим массивом элементов, отфильтрованных только для хранения элементов, которые включают по крайней мере один тег со значением Tag-32имени. Опять же, подмножество выходных данных включается здесь для краткости.

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

Создание веб-приложения ASP.NET

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

Внимание

В этом руководстве прозрачно извлекает пакеты из NuGet. Вы можете использовать dotnet nuget list source для проверки источников пакетов. Если у вас нет NuGet в качестве источника пакета, используйте dotnet nuget add source для установки сайта в качестве источника.

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

  2. cosmicworks.template.web Установите пакет шаблона проекта из NuGet.

    dotnet new install cosmicworks.template.web
    
  3. Создайте проект веб-приложения с помощью только что установленного dotnet new cosmosdbnosql-webapp шаблона.

    dotnet new cosmosdbnosql-webapp
    
  4. Создайте и запустите проект веб-приложения.

    dotnet run
    
  5. Просмотрите выходные данные команды выполнения. Выходные данные должны содержать список портов и URL-адресов, в которых выполняется приложение.

    ...
    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. Откройте новый браузер и перейдите к работающему веб-приложению. Просмотрите все три страницы запущенного приложения.

    Снимок экрана: пример веб-приложения, работающего с данными заполнителя.

  7. Остановите запущенное приложение, завершив выполняемый процесс.

    Совет

    Чтобы остановить выполняющийся процесс, используйте команду CTRL+C. Кроме того, можно закрыть и повторно открыть терминал.

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

    Совет

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

  9. Перейдите к файлу Services/ICosmosService.cs и откройте его. Обратите внимание на RetrieveActiveProductsAsync реализацию методов по умолчанию.RetrieveAllProductsAsync Эти методы создают статический список продуктов, используемых при первом запуске проекта. Здесь приведен усеченный пример одного из методов.

    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. Перейдите к файлу Services/CosmosService.cs и откройте его. Обратите внимание на текущую реализацию класса CosmosService . Этот класс реализует интерфейс ICosmosService , но не переопределяет никакие методы. В этом контексте класс будет использовать реализацию интерфейса по умолчанию, пока не будет предоставлено переопределение реализации в интерфейсе.

    public class CosmosService : ICosmosService
    { }
    
  11. Наконец, перейдите к файлам Models/Product.cs и Models/Category.cs. Просмотрите типы записей, определенные в каждом файле. Эти типы будут использоваться в запросах на протяжении всего этого руководства.

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

Запрос данных с помощью пакета SDK для .NET

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

  1. Вернитесь в терминал, добавьте Microsoft.Azure.Cosmos пакет из NuGet.

    dotnet add package Microsoft.Azure.Cosmos
    
  2. Выполните сборку проекта.

    dotnet build
    
  3. Вернитесь в Visual Studio Code, снова перейдите к файлу Services/CosmosService.cs .

  4. Добавьте новую директиву using для Microsoft.Azure.Cosmos пространств имен и Microsoft.Azure.Cosmos.Linq пространств имен.

    using Microsoft.Azure.Cosmos;
    using Microsoft.Azure.Cosmos.Linq;
    
  5. В классе CosmosService добавьте новый private readonly член типа CosmosClient с именем_client.

    private readonly CosmosClient _client;
    
  6. Создайте пустой конструктор для CosmosService класса.

    public CosmosService()
    { }
    
  7. В конструкторе создайте новый экземпляр CosmosClient класса, передавающего строковый параметр с значением PRIMARY CONNECTION STRING , которое вы ранее записали в лаборатории. Сохраните этот новый экземпляр в члене _client .

    public CosmosService()
    { 
        _client = new CosmosClient(
            connectionString: "<primary-connection-string>"
        );
    }
    
  8. Вернитесь в класс CosmosService , создайте новое private свойство типа Container с именем container. Задайте метод доступа для возврата cosmicworks базы данных и products контейнера.

    private Container container
    {
        get => _client.GetDatabase("cosmicworks").GetContainer("products");
    }
    
  9. Создайте асинхронный метод с именем RetrieveAllProductsAsync , который возвращает IEnumerable<Product>.

    public async Task<IEnumerable<Product>> RetrieveAllProductsAsync()
    { }
    
  10. Чтобы выполнить следующие действия, добавьте этот код в RetrieveAllProductsAsync метод.

    1. Используйте универсальный GetItemLinqQueryable<> метод, чтобы получить объект типа IQueryable<> , который можно использовать для создания запроса, интегрированного с языком (LINQ). Храните этот объект в переменной с именем queryable.

      var queryable = container.GetItemLinqQueryable<Product>();
      
    2. Создайте запрос LINQ с помощью Where методов расширения и OrderByDescending методов расширения. ToFeedIterator Используйте метод расширения для создания итератора для получения данных из Azure Cosmos DB и хранения итератора в переменной с именемfeed. Обтекайте все это выражение в инструкции using, чтобы удалить итератор позже.

      using FeedIterator<Product> feed = queryable
          .Where(p => p.price < 2000m)
          .OrderByDescending(p => p.price)
          .ToFeedIterator();
      
    3. Создайте переменную с именем results универсального List<> типа.

      List<Product> results = new();
      
    4. Создайте цикл времени, который будет итерировать, пока HasMoreResults свойство переменной feed не возвращает значение false. Этот цикл гарантирует, что вы выполняете цикл по всем страницам результатов на стороне сервера.

      while (feed.HasMoreResults)
      { }
      
    5. В цикле в то время асинхронно вызовите ReadNextAsync метод переменной feed и сохраните результат в переменной с именем response.

      while (feed.HasMoreResults)
      {
          var response = await feed.ReadNextAsync();
      }
      
    6. По-прежнему в течение цикла используйте цикл foreach для прохождения каждого элемента в ответе и добавления их в results список.

      while (feed.HasMoreResults)
      {
          var response = await feed.ReadNextAsync();
          foreach (Product item in response)
          {
              results.Add(item);
          }
      }
      
    7. results Возвращает список в качестве выходных RetrieveAllProductsAsync данных метода.

      return results;
      
  11. Создайте асинхронный метод с именем RetrieveActiveProductsAsync , который возвращает IEnumerable<Product>.

    public async Task<IEnumerable<Product>> RetrieveActiveProductsAsync()
    { }
    
  12. Чтобы выполнить следующие действия, добавьте этот код в RetrieveActiveProductsAsync метод.

    1. Создайте новую строку с именем sql SQL-запроса, чтобы получить несколько полей, в которых фильтр (@tagFilter) применяется к массиву тегов каждого элемента.

      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. Создайте новую QueryDefinition переменную с именем query , передаваемую в строку в sql качестве единственного параметра запроса. Кроме того, используйте WithParameter метод жидкости для применения значения red к параметру @tagFilter .

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

      using FeedIterator<Product> feed = container.GetItemQueryIterator<Product>(
          queryDefinition: query
      );
      
    4. Используйте цикл времени для итерации нескольких страниц результатов и хранения значения в универсальных именованных List<>результатах. Возвращает результаты в виде выходных RetrieveActiveProductsAsync данных метода.

      List<Product> results = new();
      
      while (feed.HasMoreResults)
      {
          FeedResponse<Product> response = await feed.ReadNextAsync();
          foreach (Product item in response)
          {
              results.Add(item);
          }
      }
      
      return results;
      
  13. Сохранитефайл Services/CosmosClient.cs .

    Совет

    Если вы не уверены, что ваш код правильный, вы можете проверка исходный код для примера кода на GitHub.

Проверка окончательного приложения

Наконец, вы запустите приложение с включенной горячей перезагрузкой . Запуск приложения проверяет, может ли ваш код получить доступ к данным из API для NoSQL.

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

    dotnet run
    
  2. Выходные данные команды выполнения должны содержать список портов и URL-адресов, в которых выполняется приложение. Откройте новый браузер и перейдите к работающему веб-приложению. Просмотрите все три страницы запущенного приложения. Теперь каждая страница должна содержать динамические данные из Azure Cosmos DB.

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

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

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

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