Übung: Lesen und Abfragen von Elementen

Abgeschlossen

Erinnern Sie sich daran, dass Ihre Anwendung sowohl Elemente zu einem Azure Cosmos DB for NoSQL-Container hinzufügen als auch diese Elemente zur Validierung wieder daraus lesen soll. An diesem Punkt fügt Ihre Anwendung dem Container erfolgreich Elemente hinzu. Es gibt zwei wesentliche Methoden zum Lesen eines Elements: durch Ausführen eines Punktlesevorgangs oder durch Ausführen einer Abfrage.

Derzeit gibt es drei wichtige Anforderungen:

  1. Punktlesen eines Elements mithilfe des eindeutigen Bezeichners und des Partitionsschlüsselwerts.
  2. Erstellen einer Abfrage mithilfe einer einfachen Abfragezeichenfolge
  3. Paginieren der Ergebnisse der Abfrage mit einem Feediterator

Illustration of icons indicating data being queried using a query.

Nachdem Sie diese Übung abgeschlossen haben, ist Ihre Anwendung fast fertig. Sie verfügen über Abfragen, die die zuvor erstellte Kategorie und die Produktelemente lesen können.

Punkt lesen eines Elements

Die einfachste Möglichkeit zum Abrufen eines Elements in Azure Cosmos DB besteht darin, einen Punktlesevorgang durchzuführen. Punktlesevorgänge verwenden eine kleine und vorhersagbare Anzahl von RUs im Vergleich zu Abfragen. Hier punktlesen Sie das einzelne Kategorieelement helmets (Helme), das Sie erstellt haben.

  1. Kehren Sie zur Datei Program.cs zurück.

  2. Erstellen Sie eine neue PartitionKey-Instanz für gear-climb-helmets.

    PartitionKey readKey = new("gear-climb-helmets");
    
  3. Verwenden Sie Container.ReadItemAsync, um ein bestimmtes Element punktzulesen, indem Sie die id-Eigenschaft und den Partitionsschlüsselwert verwenden.

    ItemResponse<Category> readResponse = await container.ReadItemAsync<Category>(
        id: "91f79374-8611-4505-9c28-3bbbf1aa7df7",
        partitionKey: readKey
    );
    
  4. Rufen Sie ihren serialisierten generischen Typ mithilfe der Resource-Eigenschaft der ItemResponse-Klasse ab.

    Category readItem = readResponse.Resource;
    
  5. Geben Sie den eindeutigen Bezeichner und die Anforderungsbelastung für den Punktlesevorgang aus.

    Console.WriteLine($"[Point read item]:\t{readItem.Id}\t(RUs: {readResponse.RequestCharge})");    
    
  6. Speichern Sie die Datei Program.cs.

Ausführen einer Abfrage

In Situationen, in denen Sie mehrere Elemente benötigen, können Sie eine Abfrage verwenden, um diese Elemente zu suchen und abzurufen. Erinnern Sie sich daran, dass wir die categoryId-Partitionsschlüsseleigenschaft verwendet haben, um unsere Elemente in bestimmte Kategorien zu gruppieren. Wenn wir diese Eigenschaft in eine Abfrage einbeziehen, erstellen wir effektiv eine Abfrage, die auf eine einzige logische Partition beschränkt ist. Verwenden Sie nun eine Abfrage, um alle Elemente in der Kategorie tents (Zelte) zu finden.

  1. Erstellen Sie in Program.cs eine neue Zeichenfolge für die Abfrage SELECT * FROM products p WHERE p.categoryId = 'gear-camp-tents'. Verwenden Sie jedoch einen Parameter namens @partitionKey für den categoryId-Filter.

    string statement = "SELECT * FROM products p WHERE p.categoryId = @partitionKey";
    
  2. Erstellen Sie eine neue Instanz der QueryDefinition-Klasse mit Ihrer Abfragezeichenfolge.

    var query = new QueryDefinition(
        query: statement
    );
    
  3. Verwenden Sie die Fluent-Methode WithParameter, um dem Parameter @partitionKey den gear-camp-tents-Wert zuzuweisen.

    var parameterizedQuery = query.WithParameter("@partitionKey", "gear-camp-tents");
    
  4. Verwenden Sie Container.GetItemQueryIterator<>, um einen Iterator für Ihre spezifische Abfrage abzurufen.

    using FeedIterator<Product> feed = container.GetItemQueryIterator<Product>(
        queryDefinition: parameterizedQuery
    );
    
  5. Schreiben Sie die Abfrage in die Konsole.

    Console.WriteLine($"[Start query]:\t{statement}");
    
  6. Speichern Sie die Datei Program.cs.

Paginieren von Abfrageergebnissen

Azure Cosmos DB teilt Ihre Abfrageergebnisse automatisch auf Seiten auf, die asynchron abgerufen werden können. Um diese Seiten zu verwalten, müssen Sie Ihren C#-Code auf eine bestimmte Weise schreiben, damit alle verfügbaren Ergebnisseiten abgerufen werden. Hier verwenden Sie eine while- und foreach-Schleife in C#, um Ergebnisseiten zu durchlaufen.

  1. Erstellen Sie in Program.cs eine neue double-Variable namens totalRequestCharge, die auf den Wert 0 festgelegt ist.

    double totalRequestCharge = 0d;
    
  2. Erstellen Sie eine while-Schleife, die durchlaufen wird, bis die FeedIterator.HasMoreResults-Eigenschaft Ihres Feediterators „false“ lautet.

    while (feed.HasMoreResults)
    {
    }
    
  3. Rufen Sie innerhalb der while-Schleife eine neue Ergebnisseite mithilfe der FeedIterator.ReadNextAsync-Methode ab.

    FeedResponse<Product> page = await feed.ReadNextAsync();
    
  4. Immer noch innerhalb der while-Schleife erhöhen Sie die Gesamtanforderungsbelastung unter Verwendung des Werts FeedResponse.RequestCharge.

    totalRequestCharge += page.RequestCharge;
    
  5. Erstellen Sie weiterhin innerhalb der while-Schleife eine neue foreach-Schleife, um die tatsächlichen Elemente auf der Seite zu durchlaufen.

    foreach (Product item in page)
    {
    }
    
  6. Schreiben Sie innerhalb der foreach-Schleife die Eigenschaften id und name des zurückgegebenen Elements in die Konsole.

    Console.WriteLine($"[Returned item]:\t{item.Id}\t(Name: {item.Name ?? "N/A"})");
    
  7. Schreiben Sie außerhalb der while-Schleife die von Ihnen berechnete Gesamtanforderungsbelastung in die Konsole.

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

    Tipp

    Wenn Sie sich nicht sicher sind, welcher Code innerhalb oder außerhalb der while- und foreach-Schleifen sein sollte, wechseln Sie zum Abschnitt Überprüfen von Code in Überprüfen Ihrer Arbeit.

  8. Speichern Sie die Datei Program.cs.

Arbeit überprüfen

Ihre App liest jetzt Elemente aus dem Container und fragt sie ab. Hier führen Sie die Anwendung aus, damit Sie die Ergebnisse beider Vorgänge beobachten können.

  1. Ausführen der .NET-Anwendung im Terminal:

    dotnet run
    
  2. Beobachten Sie die Ausgabe der Ausführung der Anwendung. Die Ausgabe sollte dem folgenden Beispiel entsprechen:

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

    Tipp

    Die in dieser Beispielausgabe gezeigten RUs können von Ihrer Ausgabe abweichen.

    Haben Sie bemerkt, dass Ihr category-Element erfolgreich in den Typ deserialisiert wurde, den Sie für products verwenden? Da das category-Element keine name-Eigenschaft besaß, wurde diese Eigenschaft auf ihrem Standardwert belassen. Typüberprüfung, Schemaverwaltung und Serialisierung/Deserialisierung sind alles Dinge, die Ihre Anwendung vollständig clientseitig verwalten kann.