Tutorial: Entwickeln einer ASP.NET-Webanwendung mit Azure Cosmos DB for NoSQL

GILT FÜR: NoSQL

Mit dem Azure SDK für .NET können Sie Daten in einer API für NoSQL-Container mithilfe von LINQ in C# oder einer SQL-Abfragezeichenfolge abfragen. In diesem Tutorial wird der Prozess zum Aktualisieren einer vorhandenen ASP.NET-Webanwendung beschrieben, die Platzhalterdaten verwendet, um stattdessen Abfragen von der API durchzuführen.

In diesem Tutorial lernen Sie Folgendes:

  • Erstellen und Auffüllen einer Datenbank und eines Containers mithilfe der API für NoSQL
  • Erstellen einer ASP.NET-Webanwendung aus einer Vorlage
  • Abfragen von Daten aus der API für NoSQL-Container mithilfe des Azure SDK für .NET

Voraussetzungen

Erstellen einer API für NoSQL-Ressourcen

Zunächst erstellen Sie eine Datenbank und einen Container im vorhandenen API für NoSQL-Konto. Anschließend füllen Sie dieses Konto mithilfe des dotnet-Tools cosmicworks mit Daten auf.

  1. Navigieren Sie im Azure-Portal zu Ihrem vorhandenen API für NoSQL-Konto.

  2. Wählen Sie im Ressourcenmenü die Option Schlüssel aus.

    Screenshot einer API für NoSQL-Kontoseite mit hervorgehobener Option „Schlüssel“ im Ressourcenmenü

  3. Sehen Sie sich auf der Seite Schlüssel die Werte im Felde PRIMÄRE VERBINDUNGSZEICHENFOLGE* an, und notieren Sie sich diese. Dieser Wert wird im gesamten Tutorial verwendet.

    Screenshot der Seite „Schlüssel“ mit hervorgehobenen Feldern „URI“, „Primärschlüssel“ und „Primärverbindungszeichenfolge“

  4. Wählen Sie im Ressourcenmenü Data Explorer aus.

    Screenshot der im Ressourcenmenü hervorgehobenen Option „Daten-Explorer“

  5. Wählen Sie auf der Seite Daten-Explorer in der Befehlsleiste die Option Neuer Container aus.

    Screenshot der Option „Neuer Container“ in der Befehlsleiste des Daten-Explorer

  6. Erstellen Sie im Dialogfeld Neuer Container einen neuen Container mit den folgenden Einstellungen:

    Einstellung Wert
    Datenbank-ID cosmicworks
    Typ des Datenbankdurchsatzes Manuell
    Menge des Datenbankdurchsatzes 1000
    Container-ID products
    Partitionsschlüssel /category/name

    Screenshot des Dialogfelds „Neuer Container“ im Daten-Explorer mit verschiedenen Werten in jedem Feld

    Wichtig

    In diesem Tutorial wird die Datenbank zunächst auf 1.000 RU/s im gemeinsam genutzten Durchsatz skaliert, um die Leistung für die Datenmigration zu maximieren. Sobald die Datenmigration abgeschlossen ist, wird der bereitgestellte Durchsatz auf 400 RU/s herunterskaliert.

  7. Wählen Sie OK aus, um die Datenbank und den Container zu erstellen.

  8. Öffnen Sie ein Terminal, um Befehle auszuführen und so den Container mit Daten aufzufüllen.

    Tipp

    Sie können optional Azure Cloud Shell verwenden.

  9. Installieren Sie v2 des dotnet-Tools cosmicworks von NuGet.

    dotnet tool install --global cosmicworks  --version 2.*
    
  10. Verwenden Sie das Tool cosmicworks, um Ihr API für NoSQL-Konto mit Beispielproduktdaten mithilfe der Werte URI und PRIMÄRSCHLÜSSEL aufzufüllen, die Sie zuvor in diesem Lab aufgezeichnet haben. Diese aufgezeichneten Werte werden jeweils für die Parameter endpoint und key verwendet.

    cosmicworks \
        --number-of-products 1759 \
        --number-of-employees 0 \
        --disable-hierarchical-partition-keys \
        --connection-string <nosql-connection-string>
    
  11. Beachten Sie die Ausgabe des Befehlszeilentools. Dies sollte dem Container 1759 Elemente hinzufügen. Die enthaltene Beispielausgabe ist der Kürze halber abgeschnitten.

    ── 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. Kehren Sie zur Seite Daten-Explorer für Ihr Konto zurück.

  13. Erweitern Sie im Abschnitt Daten den Datenbankknoten cosmicworks, und wählen Sie dann Skalieren aus.

    Screenshot der Option „Skalieren“ im Datenbankknoten

  14. Reduzieren Sie den Durchsatz von 1.000 auf 400.

    Screenshot der Durchsatzeinstellungen für die Datenbank, die auf 400 RU/s reduziert wurden

  15. Klicken Sie auf der Befehlsleiste auf Speichern.

    Screenshot der Option „Speichern“ in der Befehlsleiste des Data Explorer

  16. Erweitern Sie im Abschnitt Daten den Containerknoten products, und wählen Sie ihn aus.

    Screenshot des erweiterten Containerknotens im Datenbankknoten

  17. Wählen Sie in der Befehlsleiste die Option Neue SQL-Abfrage aus.

    Screenshot der Option „Neue SQL-Abfrage“ in der Befehlsleiste des Daten-Explorer

  18. Fügen Sie im Abfrage-Editor diese SQL-Abfragezeichenfolge hinzu.

    SELECT
      p.sku,
      p.price
    FROM products p
    WHERE p.price < 2000
    ORDER BY p.price DESC
    
  19. Wählen Sie Abfrage ausführen aus, um die Abfrage auszuführen, und sehen Sie sich die Ergebnisse an.

    Screenshot der Option „Abfrage ausführen“ in der Befehlsleiste des Daten-Explorer

  20. Die Ergebnisse sollten ein paginiertes Array aller Elemente im Container mit einem Wert price sein, der kleiner als 2.000 ist, sortiert vom höchsten zum niedrigsten Preis. Aus Gründen der Kürze ist hier nur ein Teil der Ausgabe zu sehen.

    [
      {
        "sku": "BK-R79Y-48",
        "price": 1700.99
      },
      ...
      {
        "sku": "FR-M94B-46",
        "price": 1349.6
      },
    ...
    
  21. Ersetzen Sie den Inhalt des Abfrage-Editors durch diese Abfrage, und wählen Sie dann erneut Abfrage ausführen aus, um sich dann die Ergebnisse anzuschauen.

    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. Das Ergebnis sollte ein kleineres Array von Elementen mit einem Filter darstellen, sodass nur Elemente enthalten sind, die mindestens ein Tag mit dem Wert Tag-32 für name enthalten. Aus Gründen der Kürze ist hier wieder nur ein Teil der Ausgabe zu sehen.

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

Erstellen einer ASP.NET-Webanwendung

Nun erstellen Sie mithilfe einer Beispielprojektvorlage eine neue ASP.NET-Webanwendung. Anschließend untersuchen Sie den Quellcode und führen das Beispiel aus, um sich mit der Anwendung vertraut zu machen, bevor Sie Azure Cosmos DB-Konnektivität mithilfe des Azure SDK für .NET hinzufügen.

Wichtig

In diesem Tutorial werden Pakete transparent aus NuGet abgerufen. Sie können dotnet nuget list source verwenden, um Ihre Paketquellen zu überprüfen. Wenn Sie NuGet nicht als Paketquelle nutzen, verwenden Sie dotnet nuget add source, um die Website als Quelle zu installieren.

  1. Öffnen Sie ein Terminal in einem leeren Verzeichnis.

  2. Installieren Sie das Projektvorlagenpaket cosmicworks.template.web von NuGet.

    dotnet new install cosmicworks.template.web
    
  3. Erstellen Sie mithilfe der neu installierten Vorlage dotnet new cosmosdbnosql-webapp ein neues Webanwendungsprojekt.

    dotnet new cosmosdbnosql-webapp
    
  4. Erstellen Sie das Webanwendungsprojekt, und führen Sie es aus.

    dotnet run
    
  5. Sehen Sie sich die Ausgabe des Ausführungsbefehls an. Die Ausgabe sollte eine Liste der Ports und URLs enthalten, an denen die Anwendung ausgeführt wird.

    ...
    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. Öffnen Sie ein neues Browserfenster, und navigieren Sie zur ausgeführten Webanwendung. Sehen Sie sich alle drei Seiten der ausgeführten Anwendung an.

    Screenshot der Beispielwebanwendung, die mit Platzhalterdaten ausgeführt wird

  7. Beenden Sie die ausgeführte Anwendung, indem Sie den ausgeführten Prozess beenden.

    Tipp

    Verwenden Sie den Befehl STRG+C, um einen ausgeführten Prozess zu beenden. Alternativ können Sie das Terminal schließen und erneut öffnen.

  8. Öffnen Sie Visual Studio Code, und verwenden Sie den aktuellen Projektordner als Arbeitsbereich.

    Tipp

    Sie können code . im Terminal ausführen, um Visual Studio Code zu öffnen und das Arbeitsverzeichnis automatisch als aktuellen Arbeitsbereich zu öffnen.

  9. Navigieren Sie zur Datei Services/ICosmosService.cs, und öffnen Sie sie. Beachten Sie die Standardmethodenimplementierungen RetrieveActiveProductsAsync und RetrieveAllProductsAsync. Diese Methoden erstellen eine statische Liste von Produkten, die beim erstmaligen Ausführen des Projekts zu verwenden sind. Hier sehen Sie ein gekürztes Beispiel für eine der Methoden.

    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. Navigieren Sie zur Datei Services/CosmosService.cs, und öffnen Sie sie. Sehen Sie sich die aktuelle Implementierung der Klasse CosmosService an. Diese Klasse implementiert die ICosmosService-Schnittstelle, überschreibt jedoch keine Methoden. In diesem Zusammenhang verwendet die Klasse die Standardschnittstellenimplementierung, bis eine Außerkraftsetzung der Implementierung in der Schnittstelle bereitgestellt wird.

    public class CosmosService : ICosmosService
    { }
    
  11. Navigieren Sie schließlich zu den Dateien Models/Product.cs und Models/Category.cs, und öffnen Sie sie. Sehen Sie sich den in jeder Datei definierten Datensatztyp an. Diese Typen werden in den Abfragen im gesamten Tutorial verwendet.

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

Abfragen von Daten mit dem .NET SDK

Als Nächstes fügen Sie diesem Beispielprojekt das Azure SDK für .NET hinzu und verwenden die Bibliothek, um Daten aus dem API für NoSQL-Container abzufragen.

  1. Fügen Sie im Terminal das Paket Microsoft.Azure.Cosmos aus NuGet hinzu.

    dotnet add package Microsoft.Azure.Cosmos
    
  2. Erstellen Sie das Projekt.

    dotnet build
    
  3. Navigieren Sie in Visual Studio Code erneut zur Datei Services/CosmosService.cs.

  4. Fügen Sie eine neue using-Anweisung für die Namespaces Microsoft.Azure.Cosmos und Microsoft.Azure.Cosmos.Linq hinzu.

    using Microsoft.Azure.Cosmos;
    using Microsoft.Azure.Cosmos.Linq;
    
  5. Fügen Sie in der Klasse CosmosService einen neuen private readonly-Member vom Typ CosmosClient mit dem Namen _client hinzu.

    private readonly CosmosClient _client;
    
  6. Erstellen Sie einen neuen statischen Konstruktor für die Klasse CosmosService.

    public CosmosService()
    { }
    
  7. Erstellen Sie innerhalb des Konstruktors eine neue Instanz der Klasse CosmosClient, die einen Zeichenfolgenparameter mit dem Wert PRIMÄRSVERBINDUNGSZEICHENFOLGE übergibt, den Sie zuvor im Lab aufgezeichnet haben. Speichern Sie diese neue Instanz im _client-Member.

    public CosmosService()
    { 
        _client = new CosmosClient(
            connectionString: "<primary-connection-string>"
        );
    }
    
  8. Erstellen Sie in der Klasse CosmosService eine neue private-Eigenschaft des Typs Container namens container. Legen Sie get accessor so fest, dass die Datenbank cosmicworks und der Container products zurückgegeben werden.

    private Container container
    {
        get => _client.GetDatabase("cosmicworks").GetContainer("products");
    }
    
  9. Erstellen Sie eine neue asynchrone Methode namens RetrieveAllProductsAsync, die ein Element IEnumerable<Product> zurückgibt.

    public async Task<IEnumerable<Product>> RetrieveAllProductsAsync()
    { }
    
  10. Fügen Sie für die nächsten Schritte diesen Code in der RetrieveAllProductsAsync-Methode hinzu.

    1. Verwenden Sie die generische Methode GetItemLinqQueryable<>, um ein Objekt vom Typ IQueryable<> abzurufen, das Sie zum Erstellen einer Language Integrated Query (LINQ) verwenden können. Speichern Sie das Objekt in einer Variable namens queryable.

      var queryable = container.GetItemLinqQueryable<Product>();
      
    2. Erstellen Sie eine LINQ-Abfrage mit den Erweiterungsmethoden Where und OrderByDescending. Verwenden Sie die Erweiterungsmethode ToFeedIterator, um einen Iterator zu erstellen, der Daten aus Azure Cosmos DB abruft, und den Iterator in einer Variablen namens feed zu speichern. Schließen Sie diesen gesamten Ausdruck in eine using-Anweisung ein, um den Iterator später zu entfernen.

      using FeedIterator<Product> feed = queryable
          .Where(p => p.price < 2000m)
          .OrderByDescending(p => p.price)
          .ToFeedIterator();
      
    3. Erstellen Sie eine neue Variable namens results mithilfe des generischen Typs List<>.

      List<Product> results = new();
      
    4. Erstellen Sie eine while-Schleife, die durchlaufen wird, bis die HasMoreResults-Eigenschaft der feed-Variable „false“ zurückgibt. Diese Schleife stellt sicher, dass Sie alle Seiten serverseitiger Ergebnisse durchlaufen.

      while (feed.HasMoreResults)
      { }
      
    5. Rufen Sie innerhalb der while-Schleife die ReadNextAsync-Methode der feed-Variablen asynchron auf, und speichern Sie das Ergebnis in einer Variable namens response.

      while (feed.HasMoreResults)
      {
          var response = await feed.ReadNextAsync();
      }
      
    6. Verwenden Sie in der while-Schleife eine foreach-Schleife, um jedes Element in der Antwort zu durchlaufen und sie der Liste results hinzuzufügen.

      while (feed.HasMoreResults)
      {
          var response = await feed.ReadNextAsync();
          foreach (Product item in response)
          {
              results.Add(item);
          }
      }
      
    7. Geben Sie die results-Liste als Ausgabe der RetrieveAllProductsAsync-Methode zurück.

      return results;
      
  11. Erstellen Sie eine neue asynchrone Methode namens RetrieveActiveProductsAsync, die ein Element IEnumerable<Product> zurückgibt.

    public async Task<IEnumerable<Product>> RetrieveActiveProductsAsync()
    { }
    
  12. Fügen Sie für die nächsten Schritte diesen Code in der RetrieveActiveProductsAsync-Methode hinzu.

    1. Erstellen Sie eine neue Zeichenfolge mit dem Namen sql mit einer SQL-Abfrage, um mehrere Felder abzurufen, bei denen ein Filter (@tagFilter) auf das Array tags jedes Elements angewendet wird.

      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. Erstellen Sie eine neue QueryDefinition-Variable namens query, und übergeben Sie die Zeichenfolge sql als einzigen Abfrageparameter. Verwenden Sie außerdem die Fluid-Methode WithParameter, um den Wert red auf den Parameter @tagFilter anzuwenden.

      var query = new QueryDefinition(
          query: sql
      )
          .WithParameter("@tagFilter", "red");
      
    3. Verwenden Sie die generische Methode GetItemQueryIterator<> und die Variable query, um einen Iterator zu erstellen, der Daten aus Azure Cosmos DB abruft. Speichern Sie den Iterator in einer Variable namens feed. Schließen Sie diesen gesamten Ausdruck in eine using-Anweisung ein, um den Iterator später zu entfernen.

      using FeedIterator<Product> feed = container.GetItemQueryIterator<Product>(
          queryDefinition: query
      );
      
    4. Verwenden Sie eine while-Schleife, um mehrere Seiten mit Ergebnissen zu durchlaufen und den Wert in einer generischen Methode List<> names results zu speichern. Geben Sie die Methode results als Ausgabe der RetrieveActiveProductsAsync-Methode zurück.

      List<Product> results = new();
      
      while (feed.HasMoreResults)
      {
          FeedResponse<Product> response = await feed.ReadNextAsync();
          foreach (Product item in response)
          {
              results.Add(item);
          }
      }
      
      return results;
      
  13. Speichern Sie die Datei Services/CosmosClient.cs.

    Tipp

    Wenn Sie nicht sicher sind, ob Ihr Code korrekt ist, können Sie Ihren Quellcode durch Abgleich mit dem Beispielcode auf GitHub überprüfen.

Überprüfen der endgültigen Anwendung

Abschließend führen Sie die Anwendung mit aktiviertem Hot Reload aus. Wenn Sie die Anwendung ausführen, wird überprüft, ob Ihr Code über die API für NoSQL auf Daten zugreifen kann.

  1. Führen Sie die Anwendung im Terminal aus.

    dotnet run
    
  2. Die Ausgabe des Ausführungsbefehls sollte eine Liste der Ports und URLs enthalten, in denen die Anwendung ausgeführt wird. Öffnen Sie ein neues Browserfenster, und navigieren Sie zur ausgeführten Webanwendung. Sehen Sie sich alle drei Seiten der ausgeführten Anwendung an. Jede Seite sollte jetzt Livedaten aus Azure Cosmos DB enthalten.

Bereinigen von Ressourcen

Löschen Sie die in diesem Tutorial verwendete Datenbank, falls Sie sie nicht mehr benötigen. Navigieren Sie dazu zur Kontoseite, wählen Sie Daten-Explorer und dann die Datenbank cosmicworks aus. Wählen Sie schließlich Löschen aus.

Nächste Schritte

Nachdem Sie nun ihre erste .NET-Webanwendung mithilfe von Azure Cosmos DB erstellt haben, können Sie sich jetzt intensiver mit dem SDK beschäftigen, um weitere Daten zu importieren, komplexe Abfragen auszuführen und Ihre Azure Cosmos DB for NoSQL-Ressourcen zu verwalten.