Упражнение. Чтение и запрашивание элементов

Завершено

Помните, что приложение должно добавлять элементы в контейнер Azure Cosmos DB для NoSQL и читать те же элементы обратно, что и проверка. На этом этапе приложение успешно добавляет элементы в контейнер. Существует два основных способа чтения элемента: выполнение операции чтения точек или выполнение запроса.

Сейчас существуют три основных требования:

  1. Точечное чтение элемента с использованием уникального идентификатора и значения ключа секции.
  2. Создание запроса с помощью простой строки запроса
  3. Разбиение результатов запроса с помощью итератора канала

Illustration of icons indicating data being queried using a query.

После выполнения этого упражнения ваше приложение будет почти готово. У вас есть запросы, которые могут считывать созданные ранее элементы категории и продукта.

Указание на чтение элемента

Самый простой способ получить элемент в Azure Cosmos DB — выполнить точечное чтение. Операции точечного чтения используют небольшое и прогнозируемое количество ЕЗ по сравнению с запросами. Здесь вы указываете, что вы прочитали созданный вами элемент одной категории шлемов .

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

  2. Создайте экземпляра PartitionKey для gear-climb-helmets.

    PartitionKey readKey = new("gear-climb-helmets");
    
  3. Используйте Container.ReadItemAsync для точечного чтения определенного элемента через свойство id и значение ключа секции.

    ItemResponse<Category> readResponse = await container.ReadItemAsync<Category>(
        id: "91f79374-8611-4505-9c28-3bbbf1aa7df7",
        partitionKey: readKey
    );
    
  4. Получите сериализованный универсальный тип с помощью свойства Resource класса ItemResponse.

    Category readItem = readResponse.Resource;
    
  5. Выводит уникальный идентификатор и плату за запрос для операции точечного чтения.

    Console.WriteLine($"[Point read item]:\t{readItem.Id}\t(RUs: {readResponse.RequestCharge})");    
    
  6. Сохраните файл Program.cs.

Выполнение запроса

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

  1. В Program.cs создайте новую строку для запроса SELECT * FROM products p WHERE p.categoryId = 'gear-camp-tents'. Но используйте параметр @partitionKey для фильтра categoryId.

    string statement = "SELECT * FROM products p WHERE p.categoryId = @partitionKey";
    
  2. Создайте новый экземпляр класса QueryDefinition со строкой запроса.

    var query = new QueryDefinition(
        query: statement
    );
    
  3. Используйте метод Fluent WithParameter, чтобы назначить параметру @partitionKey значение gear-camp-tents.

    var parameterizedQuery = query.WithParameter("@partitionKey", "gear-camp-tents");
    
  4. Используйте Container.GetItemQueryIterator<> , чтобы получить итератор для конкретного запроса.

    using FeedIterator<Product> feed = container.GetItemQueryIterator<Product>(
        queryDefinition: parameterizedQuery
    );
    
  5. Напишите запрос в консоль.

    Console.WriteLine($"[Start query]:\t{statement}");
    
  6. Сохраните файл Program.cs.

Разбиение результатов запроса на страницы

Azure Cosmos DB автоматически разбивает результаты запроса на страницы, которые можно получить асинхронно. Чтобы управлять этими страницами, необходимо написать код C# определенным образом, чтобы обеспечить получение всех доступных страниц результатов. Здесь вы будете использовать цикл while и foreach в C#, чтобы выполнить итерацию по страницам результатов.

  1. В Program.cs создайте новую двойнуюпеременную с именем totalRequestCharge, установленную в значение 0.

    double totalRequestCharge = 0d;
    
  2. Создайте цикл времени, который выполняет итерацию, пока свойство FeedIterator.HasMoreResults вашего итератора канала равно false.

    while (feed.HasMoreResults)
    {
    }
    
  3. Внутри цикла while получите новую страницу результатов с помощью метода FeedIterator.ReadNextAsync.

    FeedResponse<Product> page = await feed.ReadNextAsync();
    
  4. Опять внутри цикла while выполните шаг приращения общей платы за запрос, используя значение FeedResponse.RequestCharge.

    totalRequestCharge += page.RequestCharge;
    
  5. По-прежнему внутри цикла while создайте цикл foreach, чтобы выполнить итерацию по фактическим элементам на странице.

    foreach (Product item in page)
    {
    }
    
  6. Внутри цикла foreach введите в консоль свойства id и name возвращаемого элемента.

    Console.WriteLine($"[Returned item]:\t{item.Id}\t(Name: {item.Name ?? "N/A"})");
    
  7. За пределами цикла while введите в консоль общую плату за запрос, которую вы вычислили.

    Console.WriteLine($"[Query metrics]:\t(RUs: {totalRequestCharge})");
    

    Совет

    Если вы не уверены, какой код должен быть внутри циклов while и foreach, а какой за их пределами, перейдите на вкладку проверки кода в разделе Проверка работы.

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

Проверьте свою работу

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

  1. Запустите приложение .NET в терминале:

    dotnet run
    
  2. Просмотрите выходные данные запуска приложения. Выходные данные должны соответствовать примеру:

    ...
    [Point read item]:      91f79374-8611-4505-9c28-3bbbf1aa7df7    (RUs: 1)
    [Start query]:          SELECT * FROM products p WHERE p.categoryId = @partitionKey
    [Returned item]:        5df21ec5-813c-423e-9ee9-1a2aaead0be4    (Name: N/A)
    [Returned item]:        e8dddee4-9f43-4d15-9b08-0d7f36adcac8    (Name: Cirroa Tent)
    [Returned item]:        e6f87b8d-8cd7-4ade-a005-14d3e2fbd1aa    (Name: Kuloar Tent)
    [Returned item]:        f7653468-c4b8-47c9-97ff-451ee55f4fd5    (Name: Mammatin Tent)
    [Returned item]:        6e3b7275-57d4-4418-914d-14d1baca0979    (Name: Nimbolo Tent)
    [Query metrics]:        (RUs: 2.94)
    

    Совет

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

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