Skip to content

Commit cb20a53

Browse files
committed
Modification/update
1 parent 136202f commit cb20a53

File tree

5 files changed

+317
-13
lines changed

5 files changed

+317
-13
lines changed
43.2 KB
Loading
29.3 KB
Loading
130 KB
Loading

articles/cosmos-db/nosql/tutorial-dotnet-console-app.md

Lines changed: 302 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,16 @@ ms.custom: devx-track-dotnet, ignite-2022, cosmos-dev-refresh, cosmos-dev-dotnet
2020

2121
[!INCLUDE[Console app language selector](includes/tutorial-console-app-selector.md)]
2222

23-
The Azure SDK for .NET allows you to add data to an API for NoSQL container either [individually]() or by using a [transactional batch](). This tutorial will walk through the process of create a new .NET console application that adds multiple items to a container.
23+
The Azure SDK for .NET allows you to add data to an API for NoSQL container either how-to-dotnet-create-item.md#create-an-item-asynchronously or by using a [transactional batch](transactional-batch.md?tabs=dotnet). This tutorial will walk through the process of create a new .NET console application that adds multiple items to a container.
2424

2525
In this tutorial, you learn how to:
2626

2727
> [!div class="checklist"]
2828
>
2929
> - Create a database using API for NoSQL
3030
> - Create a .NET console application and add the Azure SDK for .NET
31-
> - Add and modify individual items in an API for NoSQL container
31+
> - Add individual items into an API for NoSQL container
32+
> - Modify existing items in an API for NoSQL container
3233
> - Create a transaction with batch changes for the API for NoSQL container
3334
>
3435
@@ -44,9 +45,306 @@ In this tutorial, you learn how to:
4445

4546
## Create API for NoSQL resources
4647

48+
First, create an empty database in the existing API for NoSQL account. You'll create a container using the Azure SDK for .NET later.
49+
50+
1. Navigate to your existing API for NoSQL account in the [Azure portal](https://portal.azure.com/).
51+
52+
1. In the resource menu, select **Keys**.
53+
54+
:::image type="content" source="media/tutorial-dotnet-console-app/resource-menu-keys.png" lightbox="media/tutorial-dotnet-web-app/resource-menu-keys.png" alt-text="Screenshot of an API for NoSQL account page. The Keys option is highlighted in the resource menu.":::
55+
56+
1. On the **Keys** page, observe and record the value of the **URI** and **PRIMARY KEY** fields. These values will be used throughout the tutorial.
57+
58+
:::image type="content" source="media/tutorial-dotnet-console-app/page-keys.png" alt-text="Screenshot of the Keys page with the URI and Primary Key fields highlighted.":::
59+
60+
1. In the resource menu, select **Data Explorer**.
61+
62+
:::image type="content" source="media/tutorial-dotnet-console-app/resource-menu-data-explorer.png" alt-text="Screenshot of the Data Explorer option highlighted in the resource menu.":::
63+
64+
1. On the **Data Explorer** page, select the **New Database** option in the command bar.
65+
66+
:::image type="content" source="media/tutorial-dotnet-console-app/page-data-explorer-new-database.png" alt-text="Screenshot of the New Database option in the Data Explorer command bar.":::
67+
68+
1. In the **New Database** dialog, create a new container with the following settings:
69+
70+
| | Value |
71+
| --- | --- |
72+
| **Database id** | `cosmicworks` |
73+
| **Database throughput type** | **Manual** |
74+
| **Database throughput amount** | `400` |
75+
76+
:::image type="content" source="media/tutorial-dotnet-console-app/dialog-new-database.png" alt-text="Screenshot of the New Database dialog in the Data Explorer with various values in each field.":::
77+
78+
1. Select **OK** to create the database.
79+
4780
## Create .NET console application
4881

49-
## Manage items in a container using the SDK
82+
Now, you'll create a new .NET console application and import the Azure SDK for .NET by using the `Microsoft.Azure.Cosmos` library from NuGet.
83+
84+
1. Open a terminal in an empty directory.
85+
86+
1. Create a new console application using the `console` built-in template
87+
88+
```bash
89+
dotnet new console
90+
```
91+
92+
1. Add the **3.31.1-preview** version of the `Microsoft.Azure.Cosmos` package from NuGet.
93+
94+
```bash
95+
dotnet add package Microsoft.Azure.Cosmos --version 3.31.1-preview
96+
```
97+
98+
1. Also, add the **pre-release** version of the `System.CommandLine` package from NuGet.
99+
100+
```bash
101+
dotnet add package System.CommandLine --prerelease
102+
```
103+
104+
1. Also, add the `Humanizer` package from NuGet.
105+
106+
```bash
107+
dotnet add package Humanizer
108+
```
109+
110+
1. Build the console application project.
111+
112+
```bash
113+
dotnet build
114+
```
115+
116+
1. Open Visual Studio Code using the current project folder as the workspace.
117+
118+
> [!TIP]
119+
> You can run `code .` in the terminal to open Visual Studio Code and automatically open the working directory as the current workspace.
120+
121+
1. Navigate to and open the **Program.cs** file. Delete all of the existing code in the file.
122+
123+
1. Add this code to the file to use the **System.CommandLine** library to parse the command line for two strings passed in through the `--first` and `--last` options.
124+
125+
```csharp
126+
using System.CommandLine;
127+
128+
var command = new RootCommand();
129+
130+
var nameOption = new Option<string>("--name") { IsRequired = true };
131+
var emailOption = new Option<string>("--email");
132+
var stateOption = new Option<string>("--state") { IsRequired = true };
133+
var countryOption = new Option<string>("--country") { IsRequired = true };
134+
135+
command.AddOption(nameOption);
136+
command.AddOption(emailOption);
137+
command.AddOption(stateOption);
138+
command.AddOption(countryOption);
139+
140+
command.SetHandler(
141+
handle: CosmosHandler.CreateCustomerAsync,
142+
nameOption,
143+
emailOption,
144+
stateOption,
145+
countryOption
146+
);
147+
148+
await command.InvokeAsync(args);
149+
```
150+
151+
> [!NOTE]
152+
> For this tutorial, it's not entirely important that you understand how the command-line parser works. The parser has four options that can be specified when the application is running. Three of the options are required since they will be used to construct the ID and partition key fields.
153+
154+
1. At this point, the project won't build since you haven't defined the static `CosmosHandler.CreateCustomerAsync` method yet.
155+
156+
1. **Save** the **Program.cs** file.
157+
158+
## Add items to a container using the SDK
159+
160+
Next, you'll use individual operations to add items into the API for NoSQL container. In this section, you'll define the `CosmosHandler.CreateCustomerAsync` method.
161+
162+
1. Create a new **CosmosHandler.cs** file.
163+
164+
1. In the **CosmosHandler.cs** file, add a new using directive for the `Humanizer` and `Microsoft.Azure.Cosmos` namespaces.
165+
166+
```csharp
167+
using Humanizer;
168+
using Microsoft.Azure.Cosmos;
169+
```
170+
171+
1. Create a new static class named `CosmosHandler`.
172+
173+
```csharp
174+
public static class CosmosHandler
175+
{ }
176+
```
177+
178+
1. Just to validate this app will work, create a short implementation of the static `CreateCustomerAsync` method to print the command-line input.
179+
180+
```csharp
181+
public static async Task CreateCustomerAsync(string name, string email, string state, string country)
182+
{
183+
await Console.Out.WriteLineAsync($"Hello {name} of {state}, {country}!");
184+
}
185+
```
186+
187+
1. **Save** the **CosmosHandler.cs** file.
188+
189+
1. Back in the terminal, run the application.
190+
191+
```bash
192+
dotnet run -- --name 'Mica Pereira' --state 'Washington' --country 'United States'
193+
```
194+
195+
1. The output of the command should be a fun greeting.
196+
197+
```output
198+
Hello Mica Pereira of Washington, United States!
199+
```
200+
201+
1. Return to the **CosmosHandler.cs** file.
202+
203+
1. Within the static **CosmosHandler** class, add a new `private static readonly` member of type `CosmosClient` named `_client`.
204+
205+
```csharp
206+
private static readonly CosmosClient _client;
207+
```
208+
209+
1. Create a new static constructor for the `CosmosHandler` class.
210+
211+
```csharp
212+
static CosmosHandler()
213+
{ }
214+
```
215+
216+
1. Within the constructor, create a new instance of the `CosmosClient` class passing in two string parameters with the **URI** and **PRIMARY KEY** values you previously recorded in the lab. Store this new instance in the `_client` member.
217+
218+
```csharp
219+
static CosmosHandler()
220+
{
221+
_client = new CosmosClient(
222+
accountEndpoint: "<uri>",
223+
authKeyOrResourceToken: "<primary-key>"
224+
);
225+
}
226+
```
227+
228+
1. Back within the static **CosmosHandler** class, create a new asynchronous method named `GetContainerAsync` that returns an `Container`.
229+
230+
```csharp
231+
private static async Task<Container> GetContainer()
232+
{ }
233+
```
234+
235+
1. For the next steps, add this code within the `GetContainerAsync` method.
236+
237+
1. Get the `cosmicworks` database and store it in a variable named `database`.
238+
239+
```csharp
240+
Database database = _client.GetDatabase("cosmicworks");
241+
```
242+
243+
1. Create a new generic `List<>` of `string` values within a list of hierarchical partition key paths and store it in a variable named `keyPaths`.
244+
245+
```csharp
246+
List<string> keyPaths = new()
247+
{
248+
"/address/country",
249+
"/address/state"
250+
};
251+
```
252+
253+
1. Create a new `ContainerProperties` variable with the name of the container (`customers`) and the list of partition key paths.
254+
255+
```csharp
256+
ContainerProperties properties = new(
257+
id: "customers",
258+
partitionKeyPaths: keyPaths
259+
);
260+
```
261+
262+
1. Use the `CreateContainerIfNotExistsAsync` method to supply the container properties and retrieve the container. This method will, per the name, asynchronously create the container if it doesn't already exist within the database. Return the result as the output of the `GetContainerAsync` method.
263+
264+
```csharp
265+
return await database.CreateContainerIfNotExistsAsync(
266+
containerProperties: properties
267+
);
268+
```
269+
270+
1. Delete all of the code within the `CreateCustomerAsync` method.
271+
272+
1. For the next steps, add this code within the `CreateCustomerAsync` method.
273+
274+
1. Asynchronously call the `GetContainerAsync` method and store the result in a variable named `container`.
275+
276+
```csharp
277+
Container container = await GetContainerAsync();
278+
```
279+
280+
1. Create a new variable named `id` that uses the `Kebaberize` method from **Humanizer** to transform the `name` method parameter.
281+
282+
```csharp
283+
string id = name.Kebaberize();
284+
```
285+
286+
> [!NOTE]
287+
> The `Kebaberize` method will replace all spaces with hyphens and conver the text to lowercase.
288+
289+
1. Create a new anonymous typed item using the `name`, `state`, and `country` method parameters and the `id` variable. Store the item as a variable named `customer`.
290+
291+
```csharp
292+
var customer = new {
293+
id = id,
294+
name = name,
295+
address = new {
296+
state = state,
297+
country = country
298+
}
299+
};
300+
```
301+
302+
1. Use the container's asynchronous `CreateItemAsync` method to create a new item in the container and assign the HTTP response metadata to a variable named `response`.
303+
304+
```csharp
305+
var response = await container.CreateItemAsync(customer);
306+
```
307+
308+
1. Write the values of the `response` variable's `StatusCode` and `RequestCharge` properties to the console. Also write the value of the `id` variable.
309+
310+
```csharp
311+
Console.WriteLine($"[{response.StatusCode}]\t{id}\t{response.RequestCharge} RUs");
312+
```
313+
314+
1. **Save** the **CosmosHandler.cs** file.
315+
316+
1. Back in the terminal, run the application again.
317+
318+
```bash
319+
dotnet run -- --name 'Mica Pereira' --state 'Washington' --country 'United States'
320+
```
321+
322+
1. The output of the command should include a status and request charge for the operation.
323+
324+
```output
325+
[Created] mica-pereira 7.05 RUs
326+
```
327+
328+
> [!NOTE]
329+
> Your request charge may vary.
330+
331+
1. Run the application one more time.
332+
333+
```bash
334+
dotnet run -- --name 'Mica Pereira' --state 'Washington' --country 'United States'
335+
```
336+
337+
1. This time, the program should crash. If you scroll through the error message, you'll see the crash occurred because of a conflict in the unique identifier for the items.
338+
339+
```output
340+
Unhandled exception: Microsoft.Azure.Cosmos.CosmosException : Response status code does not indicate success: Conflict (409);Reason: (
341+
Errors : [
342+
"Resource with specified id or name already exists."
343+
]
344+
);
345+
```
346+
347+
## Change existing items in a container using the SDK
50348
51349
## Create a transaction using the SDK
52350
@@ -59,4 +357,4 @@ When no longer needed, delete the database used in this tutorial. To do so, navi
59357
Now that you've created your first .NET console application using Azure Cosmos DB, try the next tutorial where you'll update an existing web application to use Azure Cosmos DB data.
60358
61359
> [!div class="nextstepaction"]
62-
> [Tutorial: Develop an ASP.NET web application with Azure Cosmos DB for NoSQL](tutorial-dotnet-web-app.md)
360+
> [Tutorial: Develop an ASP.NET web application with Azure Cosmos DB for NoSQL](tutorial-dotnet-web-app.md)

0 commit comments

Comments
 (0)