Tutorial: Entwickeln einer .NET-Konsolenanwendung mit Azure Cosmos DB for NoSQL
GILT FÜR: NoSQL
Mit dem Azure SDK für .NET können Sie Daten zu einer API für NoSQL-Container hinzufügen, und zwar entweder asynchrone einzelne Vorgänge oder einen transaktionalen Batch. In diesem Tutorial erfahren Sie, wie Sie eine neue .NET-Konsolenanwendung erstellen, die einem Container mehrere Elemente hinzufügt.
In diesem Tutorial lernen Sie Folgendes:
- Erstellen einer Datenbank mithilfe der API für NoSQL
- Erstellen einer .NET-Konsolenanwendung und Hinzufügen des Azure SDK für .NET
- Hinzufügen einzelner Elemente zu einem API für NoSQL-Container
- Effizientes Abrufen von Elementen aus einem API für NoSQL-Container
- Erstellen einer Transaktion mit Batchänderungen für den API für NoSQL-Container
Voraussetzungen
- Ein vorhandenes Azure Cosmos DB for NoSQL-Konto
- Falls Sie bereits über ein vorhandenes Azure-Abonnement verfügen, erstellen Sie ein neues Konto.
- Kein Azure-Abonnement? Sie können Azure Cosmos DB kostenlos testen, ohne dass eine Kreditkarte erforderlich ist.
- Visual Studio Code
- .NET 8 oder höher
- Erfahrung mit dem Schreiben von C#-Anwendungen
Erstellen von API für NoSQL-Ressourcen
Erstellen Sie zunächst eine leere Datenbank im vorhandenen API für NoSQL-Konto. Später erstellen Sie mithilfe des Azure SDK für .NET einen Container.
Navigieren Sie im Azure-Portal zu Ihrem vorhandenen API für NoSQL-Konto.
Wählen Sie im Ressourcenmenü die Option Schlüssel aus.
Sehen Sie sich auf der Seite Schlüssel die Werte in den Feldern URI und PRIMÄRSCHLÜSSEL an, und notieren Sie sich diese. Diese Werte werden im gesamten Tutorial verwendet.
Wählen Sie im Ressourcenmenü Data Explorer aus.
Wählen Sie auf der Seite Daten-Explorer in der Befehlsleiste die Option Neue Datenbank aus.
Erstellen Sie im Dialogfeld Neue Datenbank einen neuen Container mit den folgenden Einstellungen:
Wert Datenbank-ID cosmicworks
Typ des Datenbankdurchsatzes Manuell Menge des Datenbankdurchsatzes 400
Wählen Sie OK aus, um die Datenbank zu erstellen.
Erstellen einer .NET-Konsolenanwendung
Jetzt erstellen Sie eine neue .NET-Konsolenanwendung und importieren das Azure SDK für .NET mithilfe der Microsoft.Azure.Cosmos
-Bibliothek aus NuGet.
Öffnen Sie ein Terminal in einem leeren Verzeichnis.
Erstellen Sie eine neue Konsolenanwendung mithilfe der integrierten
console
-Vorlage.dotnet new console --langVersion preview
Fügen Sie die Version 3.31.1-preview des
Microsoft.Azure.Cosmos
-Pakets aus NuGet hinzu.dotnet add package Microsoft.Azure.Cosmos --version 3.31.1-preview
Fügen Sie außerdem die Vorabversion (prerelease) des
System.CommandLine
-Pakets aus NuGet hinzu.dotnet add package System.CommandLine --prerelease
Fügen Sie außerdem das
Humanizer
-Paket aus NuGet hinzu.dotnet add package Humanizer
Erstellen Sie das Konsolenanwendungsprojekt.
dotnet build
Ö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.Navigieren Sie zur Datei Program.cs, und öffnen Sie sie. Löschen Sie den gesamten vorhandenen Code in der Datei.
Fügen Sie diesen Code in die Datei ein, um mithilfe der System.CommandLine-Bibliothek die Befehlszeile auf zwei Zeichenfolgen zu analysieren, die über die Optionen
--first
und--last
übergeben werden.using System.CommandLine; var command = new RootCommand(); var nameOption = new Option<string>("--name") { IsRequired = true }; var emailOption = new Option<string>("--email"); var stateOption = new Option<string>("--state") { IsRequired = true }; var countryOption = new Option<string>("--country") { IsRequired = true }; command.AddOption(nameOption); command.AddOption(emailOption); command.AddOption(stateOption); command.AddOption(countryOption); command.SetHandler( handle: CosmosHandler.ManageCustomerAsync, nameOption, emailOption, stateOption, countryOption ); await command.InvokeAsync(args);
Hinweis
Für dieses Tutorial müssen Sie nicht unbedingt verstehen, wie der Befehlszeilenparser funktioniert. Der Parser verfügt über vier Optionen, die beim Ausführen der Anwendung angegeben werden können. Drei der Optionen sind erforderlich, da sie zum Erstellen der Felder für ID und Partitionsschlüssel verwendet werden.
An diesem Punkt wird das Projekt nicht erstellt, da Sie die statische Methode
CosmosHandler.ManageCustomerAsync
noch nicht definiert haben.Speichern Sie die Datei Program.cs.
Hinzufügen von Elementen zu einem Container mithilfe des SDK
Als Nächstes verwenden Sie einzelne Vorgänge, um Elemente zum API für NoSQL-Container hinzuzufügen. In diesem Abschnitt definieren Sie die Methode CosmosHandler.ManageCustomerAsync
.
Erstellen Sie eine neue Datei CosmosHandler.cs.
Fügen Sie in der Datei CosmosHandler.cs eine neue using-Direktive für die Namespaces
Humanizer
undMicrosoft.Azure.Cosmos
hinzu.using Humanizer; using Microsoft.Azure.Cosmos;
Erstellen Sie eine neue statische Klasse mit dem Namen
CosmosHandler
.public static class CosmosHandler { }
Um zu überprüfen, ob diese App funktioniert, erstellen Sie eine kurze Implementierung der statischen
ManageCustomerAsync
-Methode, um die Befehlszeileneingabe zu drucken.public static async Task ManageCustomerAsync(string name, string email, string state, string country) { await Console.Out.WriteLineAsync($"Hello {name} of {state}, {country}!"); }
Speichern Sie die Datei CosmosHandler.cs.
Führen Sie die Anwendung im Terminal aus.
dotnet run -- --name 'Mica Pereira' --state 'Washington' --country 'United States'
Die Ausgabe des Befehls sollte eine lustige Begrüßung sein.
Hello Mica Pereira of Washington, United States!
Kehren Sie zur Datei CosmosHandler.cs zurück.
Fügen Sie innerhalb der statischen CosmosHandler-Klasse einen neuen
private static readonly
-Member vom TypCosmosClient
mit dem Namen_client
hinzu.private static readonly CosmosClient _client;
Erstellen Sie einen neuen statischen Konstruktor für die
CosmosHandler
-Klasse.static CosmosHandler() { }
Erstellen Sie innerhalb des Konstruktors eine neue Instanz der
CosmosClient
-Klasse, und übergeben Sie zwei Zeichenfolgenparameter mit den Werten für URI und PRIMÄRSCHLÜSSEL, die Sie zuvor im Lab notiert haben. Speichern Sie diese neue Instanz im_client
-Member.static CosmosHandler() { _client = new CosmosClient( accountEndpoint: "<uri>", authKeyOrResourceToken: "<primary-key>" ); }
Erstellen Sie in der statischen CosmosHandler-Klasse eine neue asynchrone Methode namens
GetContainerAsync
, die einenContainer
zurückgibt.private static async Task<Container> GetContainerAsync() { }
Fügen Sie für die nächsten Schritte diesen Code in der
GetContainerAsync
-Methode hinzu.Rufen Sie die Datenbank
cosmicworks
ab, und speichern Sie sie in einer Variablen namensdatabase
.Database database = _client.GetDatabase("cosmicworks");
Erstellen Sie eine neue generische
List<>
vonstring
-Werten in einer Liste von hierarchischen Partitionsschlüsselpfaden, und speichern Sie sie in einer Variablen namenskeyPaths
.List<string> keyPaths = new() { "/address/country", "/address/state" };
Erstellen Sie eine neue
ContainerProperties
-Variable mit dem Namen des Containers (customers
) und der Liste der Partitionsschlüsselpfade.ContainerProperties properties = new( id: "customers", partitionKeyPaths: keyPaths );
Verwenden Sie die Methode
CreateContainerIfNotExistsAsync
, um die Containereigenschaften anzugeben und den Container abzurufen. Wie der Name schon sagt, erstellt diese Methode den Container asynchron, wenn er noch nicht in der Datenbank vorhanden ist. Geben Sie das Ergebnis als Ausgabe derGetContainerAsync
-Methode zurück.return await database.CreateContainerIfNotExistsAsync( containerProperties: properties );
Löschen Sie den gesamten Code innerhalb der
ManageCustomerAsync
-Methode.Fügen Sie für die nächsten Schritte diesen Code in der
ManageCustomerAsync
-Methode hinzu.Rufen Sie die
GetContainerAsync
-Methode asynchron auf, und speichern Sie das Ergebnis in einer Variable namenscontainer
.Container container = await GetContainerAsync();
Erstellen Sie eine neue Variable namens
id
, die dieKebaberize
-Methode von Humanizer verwendet, um den Methodenparametername
zu transformieren.string id = name.Kebaberize();
Hinweis
Die
Kebaberize
-Methode ersetzt alle Leerzeichen durch Bindestriche und wandelt den Text in Kleinbuchstaben um.Erstellen Sie ein neues Element vom anonymen Typ mit den Methodenparametern
name
,state
undcountry
und der Variablenid
. Speichern Sie das Element als Variable namenscustomer
.var customer = new { id = id, name = name, address = new { state = state, country = country } };
Verwenden Sie die asynchrone
CreateItemAsync
-Methode des Containers, um ein neues Element im Container zu erstellen und die HTTP-Antwortmetadaten einer Variablen namensresponse
zuzuweisen.var response = await container.CreateItemAsync(customer);
Schreiben Sie die Werte der Eigenschaften
StatusCode
undRequestCharge
derresponse
-Variablen in die Konsole. Schreiben Sie auch den Wert der Variablenid
.Console.WriteLine($"[{response.StatusCode}]\t{id}\t{response.RequestCharge} RUs");
Speichern Sie die Datei CosmosHandler.cs.
Führen Sie die Anwendung im Terminal erneut aus.
dotnet run -- --name 'Mica Pereira' --state 'Washington' --country 'United States'
Die Ausgabe des Befehls sollte einen Status und eine Anforderungsgebühr für den Vorgang enthalten.
[Created] mica-pereira 7.05 RUs
Hinweis
Die Anforderungsgebühr kann variieren.
Führen Sie die Anwendung noch einmal aus.
dotnet run -- --name 'Mica Pereira' --state 'Washington' --country 'United States'
Dieses Mal sollte das Programm abstürzen. Wenn Sie durch die Fehlermeldung scrollen, stellen Sie fest, dass der Absturz durch einen Konflikt im eindeutigen Bezeichner für die Elemente verursacht wurde.
Unhandled exception: Microsoft.Azure.Cosmos.CosmosException : Response status code does not indicate success: Conflict (409);Reason: ( Errors : [ "Resource with specified id or name already exists." ] );
Abrufen eines Elements mithilfe des SDK
Nachdem Sie nun das erste Element im Container erstellt haben, können Sie dasselbe SDK zum Abrufen des Elements verwenden. In diesem Abschnitt fragen Sie das Element ab und führen einen Punktlesevorgang durch, um den Unterschied beim Verbrauch von Anforderungseinheiten (RU) zu vergleichen.
Kehren Sie zur Datei CosmosHandler.cs zurück bzw. öffnen Sie diese Datei.
Löschen Sie alle Codezeilen aus der
ManageCustomerAsync
-Methode mit Ausnahme der ersten beiden Zeilen.public static async Task ManageCustomerAsync(string name, string email, string state, string country) { Container container = await GetContainerAsync(); string id = name.Kebaberize(); }
Fügen Sie für die nächsten Schritte diesen Code in der
ManageCustomerAsync
-Methode hinzu.Verwenden Sie die asynchrone
CreateItemAsync
-Methode des Containers, um ein neues Element im Container zu erstellen und die HTTP-Antwortmetadaten einer Variablen namensresponse
zuzuweisen.var response = await container.CreateItemAsync(customer);
Erstellen Sie eine neue Zeichenfolge namens
sql
mit einer SQL-Abfrage, um Elemente abzurufen, auf die ein Filter (@id
) zutrifft.string sql = @" SELECT * FROM customers c WHERE c.id = @id ";
Erstellen Sie eine neue
QueryDefinition
-Variable namensquery
, und übergeben Sie die Zeichenfolgesql
als einzigen Abfrageparameter. Verwenden Sie außerdem die Fluid-MethodeWithParameter
, um den Wert der Variablenid
auf den Parameter@id
anzuwenden.var query = new QueryDefinition( query: sql ) .WithParameter("@id", id);
Verwenden Sie die generische Methode
GetItemQueryIterator<>
und die Variablequery
, um einen Iterator zu erstellen, der Daten aus Azure Cosmos DB abruft. Speichern Sie den Iterator in einer Variable namensfeed
. Schließen Sie diesen gesamten Ausdruck in eine using-Anweisung ein, um den Iterator später zu entfernen.using var feed = container.GetItemQueryIterator<dynamic>( queryDefinition: query );
Rufen Sie die
ReadNextAsync
-Methode der Variablenfeed
asynchron auf, und speichern Sie das Ergebnis in einer Variable namensresponse
.var response = await feed.ReadNextAsync();
Schreiben Sie die Werte der Eigenschaften
StatusCode
undRequestCharge
derresponse
-Variablen in die Konsole. Schreiben Sie auch den Wert der Variablenid
.Console.WriteLine($"[{response.StatusCode}]\t{id}\t{response.RequestCharge} RUs");
Speichern Sie die Datei CosmosHandler.cs.
Führen Sie die Anwendung im Terminal aus, um das einzelne Element mithilfe einer SQL-Abfrage zu lesen.
dotnet run -- --name 'Mica Pereira' --state 'Washington' --country 'United States'
Die Ausgabe des Befehls sollte angeben, dass für die Abfrage mehrere Anforderungseinheiten (Request Units, RUs) erforderlich waren.
[OK] mica-pereira 2.82 RUs
Löschen Sie in der Datei CosmosHandler.cs erneut alle Codezeilen aus der
ManageCustomerAsync
-Methode mit Ausnahme der ersten beiden Zeilen.public static async Task ManageCustomerAsync(string name, string email, string state, string country) { Container container = await GetContainerAsync(); string id = name.Kebaberize(); }
Fügen Sie für die nächsten Schritte diesen Code in der
ManageCustomerAsync
-Methode hinzu.Erstellen Sie eine neue Instanz von
PartitionKeyBuilder
, indem Sie die Parameterstate
undcountry
als mehrteiligen Partitionsschlüsselwert hinzufügen.var partitionKey = new PartitionKeyBuilder() .Add(country) .Add(state) .Build();
Verwenden Sie die
ReadItemAsync<>
-Methode des Containers, um einen Punktlesevorgang für das Element im Container mithilfe der Variablenid
undpartitionKey
durchzuführen. Speichern Sie das Ergebnis in einer Variablen namensresponse
.var response = await container.ReadItemAsync<dynamic>( id: id, partitionKey: partitionKey );
Schreiben Sie die Werte der Eigenschaften
StatusCode
undRequestCharge
derresponse
-Variablen in die Konsole. Schreiben Sie auch den Wert der Variablenid
.Console.WriteLine($"[{response.StatusCode}]\t{id}\t{response.RequestCharge} RU");
Speichern Sie die Datei CosmosHandler.cs erneut.
Führen Sie die Anwendung noch einmal im Terminal aus, um einen Punktlesevorgang für das einzelne Element durchzuführen.
dotnet run -- --name 'Mica Pereira' --state 'Washington' --country 'United States'
Die Ausgabe des Befehls sollte angeben, dass für die Abfrage eine einzelne RU erforderlich war.
[OK] mica-pereira 1 RUs
Erstellen einer Transaktion mithilfe des SDK
Zum Schluss nehmen Sie das von Ihnen erstellte Element, lesen das Element und erstellen ein anderes zugehöriges Element als Teil einer einzelnen Transaktion mithilfe des Azure SDK für .NET.
Kehren Sie zur Datei CosmosHandler.cs zurück bzw. öffnen Sie diese Datei.
Löschen Sie diese Codezeilen aus der
ManageCustomerAsync
-Methode.var response = await container.ReadItemAsync<dynamic>( id: id, partitionKey: partitionKey ); Console.WriteLine($"[{response.StatusCode}]\t{id}\t{response.RequestCharge} RUs");
Fügen Sie für die nächsten Schritte diesen neuen Code in der
ManageCustomerAsync
-Methode hinzu.Erstellen Sie ein neues Element vom anonymen Typ mit den Methodenparametern
name
,state
undcountry
und der Variablenid
. Speichern Sie das Element als Variable namenscustomerCart
. Dieses Element stellt einen Einkaufswagen für den Kunden in Echtzeit dar, der derzeit leer ist.var customerCart = new { id = $"{Guid.NewGuid()}", customerId = id, items = new string[] {}, address = new { state = state, country = country } };
Erstellen Sie ein weiteres, neues Element vom anonymen Typ mit den Methodenparametern
name
,state
undcountry
und der Variablenid
. Speichern Sie das Element als Variable namenscustomerCart
. Dieses Element stellt Versand- und Kontaktinformationen für den Kunden dar.var customerContactInfo = new { id = $"{id}-contact", customerId = id, email = email, location = $"{state}, {country}", address = new { state = state, country = country } };
Erstellen Sie einen neuen Batch mithilfe der
CreateTransactionalBatch
-Methode des Containers, und übergeben Sie die VariablepartitionKey
. Speichern Sie den Batch in einer Variable namensbatch
. Verwenden Sie Fluent-Methoden zum Ausführen der folgenden Aktionen:Methode Parameter ReadItem
Zeichenfolgenvariable id
CreateItem
Variable vom anonymen Typ customerCart
CreateItem
Variable vom anonymen Typ customerContactInfo
var batch = container.CreateTransactionalBatch(partitionKey) .ReadItem(id) .CreateItem(customerCart) .CreateItem(customerContactInfo);
Verwenden Sie die
ExecuteAsync
-Methode des Batchs, um die Transaktion zu starten. Speichern Sie das Ergebnis in einer Variablen namensresponse
.using var response = await batch.ExecuteAsync();
Schreiben Sie die Werte der Eigenschaften
StatusCode
undRequestCharge
derresponse
-Variablen in die Konsole. Schreiben Sie auch den Wert der Variablenid
.Console.WriteLine($"[{response.StatusCode}]\t{response.RequestCharge} RUs");
Speichern Sie die Datei CosmosHandler.cs erneut.
Führen Sie die Anwendung noch einmal im Terminal aus, um einen Punktlesevorgang für das einzelne Element durchzuführen.
dotnet run -- --name 'Mica Pereira' --state 'Washington' --country 'United States'
Die Ausgabe des Befehls sollte die Anforderungseinheiten anzeigen, die für die gesamte Transaktion verwendet wurden.
[OK] 16.05 RUs
Hinweis
Die Anforderungsgebühr kann variieren.
Überprüfen der endgültigen Daten im Daten-Explorer
Zum Abschluss verwenden Sie den Daten-Explorer im Azure-Portal, um die Daten und den Container anzuzeigen, die Sie in diesem Tutorial erstellt haben.
Navigieren Sie im Azure-Portal zu Ihrem vorhandenen API für NoSQL-Konto.
Wählen Sie im Ressourcenmenü Data Explorer aus.
Erweitern Sie auf der Seite Daten-Explorer die Datenbank
cosmicworks
, und wählen Sie dann den Containercustomers
aus.Wählen Sie in der Befehlsleiste die Option Neue SQL-Abfrage aus.
Sehen Sie sich im Abfrage-Editor diese SQL-Abfragezeichenfolge an.
SELECT * FROM c
Wählen Sie Abfrage ausführen aus, um die Abfrage auszuführen, und sehen Sie sich die Ergebnisse an.
Die Ergebnisse sollten ein JSON-Array mit drei Elementen enthalten, die in diesem Tutorial erstellt wurden. Beachten Sie, dass alle Elemente denselben hierarchischen Partitionsschlüsselwert, aber eindeutige ID-Felder aufweisen. Die enthaltene Beispielausgabe ist zu Kürzungszwecken abgeschnitten.
[ { "id": "mica-pereira", "name": "Mica Pereira", "address": { "state": "Washington", "country": "United States" }, ... }, { "id": "33d03318-6302-4559-b5c0-f3cc643b2f38", "customerId": "mica-pereira", "items": [], "address": { "state": "Washington", "country": "United States" }, ... }, { "id": "mica-pereira-contact", "customerId": "mica-pereira", "email": null, "location": "Washington, United States", "address": { "state": "Washington", "country": "United States" }, ... } ]
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.