Упражнение. Чтение и запрашивание элементов
Помните, что приложение должно добавлять элементы в контейнер Azure Cosmos DB для NoSQL и читать те же элементы обратно, что и проверка. На этом этапе приложение успешно добавляет элементы в контейнер. Существует два основных способа чтения элемента: выполнение операции чтения точек или выполнение запроса.
Сейчас существуют три основных требования:
- Точечное чтение элемента с использованием уникального идентификатора и значения ключа секции.
- Создание запроса с помощью простой строки запроса
- Разбиение результатов запроса с помощью итератора канала
После выполнения этого упражнения ваше приложение будет почти готово. У вас есть запросы, которые могут считывать созданные ранее элементы категории и продукта.
Указание на чтение элемента
Самый простой способ получить элемент в Azure Cosmos DB — выполнить точечное чтение. Операции точечного чтения используют небольшое и прогнозируемое количество ЕЗ по сравнению с запросами. Здесь вы указываете, что вы прочитали созданный вами элемент одной категории шлемов .
Вернитесь к файлу Program.cs .
Создайте экземпляра PartitionKey для
gear-climb-helmets
.PartitionKey readKey = new("gear-climb-helmets");
Используйте Container.ReadItemAsync для точечного чтения определенного элемента через свойство id и значение ключа секции.
ItemResponse<Category> readResponse = await container.ReadItemAsync<Category>( id: "91f79374-8611-4505-9c28-3bbbf1aa7df7", partitionKey: readKey );
Получите сериализованный универсальный тип с помощью свойства Resource класса ItemResponse.
Category readItem = readResponse.Resource;
Выводит уникальный идентификатор и плату за запрос для операции точечного чтения.
Console.WriteLine($"[Point read item]:\t{readItem.Id}\t(RUs: {readResponse.RequestCharge})");
Сохраните файл Program.cs.
Выполнение запроса
В ситуациях, когда требуется несколько элементов, можно использовать запрос для поиска и извлечения этих элементов. Помните, что мы использовали свойство ключа секции categoryId для группировки элементов по определенным категориям. Если включить это свойство в запрос, мы фактически создадим запрос область в одну логическую секцию. Теперь вы используете запрос для поиска всех элементов в категории палаток .
В Program.cs создайте новую строку для запроса
SELECT * FROM products p WHERE p.categoryId = 'gear-camp-tents'
. Но используйте параметр@partitionKey
для фильтра categoryId.string statement = "SELECT * FROM products p WHERE p.categoryId = @partitionKey";
Создайте новый экземпляр класса QueryDefinition со строкой запроса.
var query = new QueryDefinition( query: statement );
Используйте метод Fluent WithParameter, чтобы назначить параметру
@partitionKey
значениеgear-camp-tents
.var parameterizedQuery = query.WithParameter("@partitionKey", "gear-camp-tents");
Используйте Container.GetItemQueryIterator<> , чтобы получить итератор для конкретного запроса.
using FeedIterator<Product> feed = container.GetItemQueryIterator<Product>( queryDefinition: parameterizedQuery );
Напишите запрос в консоль.
Console.WriteLine($"[Start query]:\t{statement}");
Сохраните файл Program.cs.
Разбиение результатов запроса на страницы
Azure Cosmos DB автоматически разбивает результаты запроса на страницы, которые можно получить асинхронно. Чтобы управлять этими страницами, необходимо написать код C# определенным образом, чтобы обеспечить получение всех доступных страниц результатов. Здесь вы будете использовать цикл while и foreach в C#, чтобы выполнить итерацию по страницам результатов.
В Program.cs создайте новую двойнуюпеременную с именем totalRequestCharge, установленную в значение
0
.double totalRequestCharge = 0d;
Создайте цикл времени, который выполняет итерацию, пока свойство FeedIterator.HasMoreResults вашего итератора канала равно false.
while (feed.HasMoreResults) { }
Внутри цикла while получите новую страницу результатов с помощью метода FeedIterator.ReadNextAsync.
FeedResponse<Product> page = await feed.ReadNextAsync();
Опять внутри цикла while выполните шаг приращения общей платы за запрос, используя значение FeedResponse.RequestCharge.
totalRequestCharge += page.RequestCharge;
По-прежнему внутри цикла while создайте цикл foreach, чтобы выполнить итерацию по фактическим элементам на странице.
foreach (Product item in page) { }
Внутри цикла foreach введите в консоль свойства id и name возвращаемого элемента.
Console.WriteLine($"[Returned item]:\t{item.Id}\t(Name: {item.Name ?? "N/A"})");
За пределами цикла while введите в консоль общую плату за запрос, которую вы вычислили.
Console.WriteLine($"[Query metrics]:\t(RUs: {totalRequestCharge})");
Совет
Если вы не уверены, какой код должен быть внутри циклов while и foreach, а какой за их пределами, перейдите на вкладку проверки кода в разделе Проверка работы.
Сохраните файл Program.cs.
Проверьте свою работу
Теперь приложение считывает и запрашивает элементы из контейнера. Здесь вы запустите приложение, чтобы просмотреть результаты обеих операций.
Запустите приложение .NET в терминале:
dotnet run
Просмотрите выходные данные запуска приложения. Выходные данные должны соответствовать примеру:
... [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)
Совет
ЕЗ в этом примере выходных данных могут отличаться от тех, которые в ваших выходных данных.
Вы заметили, что элемент категории успешно десериализирован в тип, используемый для продуктов? Так как элемент категории не имеет свойства имени , это свойство осталось для его значения по умолчанию. Проверка типов, управление схемами и сериализация или десериализация — это все, чем приложение может полностью управлять на стороне клиента.