Hello! In our previous lesson, we laid the groundwork by programmatically creating a Cosmos DB account, database, and container. We saw how the partition key you choose in your design is specified in code when the container is created. Now, with our container ready, it's time to populate it with data.
This lesson directly addresses the learning outcome: Perform CRUD operations on Cosmos DB items using the .NET SDK. We will build on your strong .NET and web development background to create, read, update, and delete items (which are essentially JSON documents) within the container we provisioned. You'll be working with the Microsoft.Azure.Cosmos data plane SDK, which is the primary tool for application developers interacting with Cosmos DB.
The architecture we'll be building is a common pattern in modern applications, which you'll likely find very familiar.

1. Key SDK Objects and Data Models
Before diving into the code, let's quickly review the essential classes from the Microsoft.Azure.Cosmos SDK that we'll use for data operations.
Quickstart: Use Azure Cosmos DB for NoSQL with Azure SDK for .NET
This section from the official Microsoft documentation provides a concise definition of the core classes in the SDK.
Focus on the descriptions for CosmosClient, Database, Container, and PartitionKey under the "Object model" heading. These are the building blocks for all our operations.
To summarize, your code will follow this pattern:
- Instantiate a
CosmosClient(typically once per application lifetime). - Get a
Databaseobject reference from the client. - Get a
Containerobject reference from the database. - Use the
Containerobject to perform all item operations. For many of these operations, you will also need to provide aPartitionKey.
Since Cosmos DB stores data as JSON documents, we need a way to represent these documents in our C# code. The standard approach is to use Plain Old C# Objects (POCOs) or Records. The SDK handles the serialization and deserialization between your C# objects and the JSON stored in Cosmos DB.
2. A Practical Walkthrough: Building a CRUD API
The best way to learn these operations is to see them in a realistic context. We will follow a video tutorial that builds a complete .NET 8 Web API to manage a collection of "drivers" in Cosmos DB. This example uses a repository pattern, which is an excellent design choice for separating data access logic from your API controllers.
.NET 8 💥 - Create CRUD with Cosmos DB - Step by Step
This video by Mohamad Lawand provides a step-by-step guide to building a CRUD API with .NET and Cosmos DB. We'll start with the project setup and modeling.
Please watch the following segments: Project Setup: This covers installing the Microsoft.Azure.Cosmos NuGet package and configuring the connection details in appsettings.json. Data Model: Here, the Driver class is created. Notice the use of the [JsonProperty(PropertyName = "...")] attribute to control how C# properties (typically PascalCase) are serialized to JSON field names (typically camelCase). Repository Pattern: The instructor sets up an IDriverRepository interface and a DriverRepository implementation. Pay attention to how the CosmosClient and Container objects are initialized in the repository's constructor.
This setup establishes a clean and testable structure. All our Cosmos DB logic will be encapsulated within the DriverRepository class.
3. Implementing the CRUD Methods
Now we get to the core of the lesson: implementing the methods for each CRUD operation. We will use the Container object to call the specific async methods provided by the SDK.
Create: CreateItemAsync
To add a new item to the container, you use the CreateItemAsync method. This method will fail if an item with the same id already exists.
.NET 8 💥 - Create CRUD with Cosmos DB - Step by Step
This segment shows the implementation for adding a new driver.
Watch from the Create method. The key line of code is _container.CreateItemAsync(driver, new PartitionKey(driver.Team)). You must provide the object to be created and its partition key.
An alternative is UpsertItemAsync. As the name implies, it will update the item if it exists or insert it if it doesn't. This is often more convenient and can prevent race conditions. The Microsoft documentation lab uses this approach.
Read: ReadItemAsync and GetItemQueryIterator
There are two primary ways to read data:
- Point Read (Single Item): To fetch one specific item, you use
ReadItemAsync. This is the most efficient way to retrieve an item, as it requires both the item'sidand itspartitionKey.
.NET 8 💥 - Create CRUD with Cosmos DB - Step by Step
This part covers fetching a single item by its ID and partition key.
Watch the implementation of the Get driver by ID method from the Read method. The essential call is _container.ReadItemAsync<Driver>(id, new PartitionKey(team)).
- Query (Multiple Items): To retrieve multiple items, you use a SQL query. The
GetItemQueryIteratormethod executes a query and returns an iterator that you can use to loop through the paginated results.
.NET 8 💥 - Create CRUD with Cosmos DB - Step by Step
This segment demonstrates how to query for all items in the container.
Watch the Get All implementation from the Query method. Note the pattern: define a query, get the iterator, and then loop while HasMoreResults is true, calling ReadNextAsync to get each page of results.
Update: ReplaceItemAsync
To update an existing item, you use ReplaceItemAsync. This method replaces the entire document with the new version you provide. You must first fetch the item, modify it in your application code, and then send the entire modified object back. The item must already exist for this call to succeed.
.NET 8 💥 - Create CRUD with Cosmos DB - Step by Step
This section covers the update logic.
Watch the Update implementation from the Update method. The video's code uses a method named update item async, which corresponds to ReplaceItemAsync in the SDK. Notice the call requires the entire updated driver object and its partitionKey.
Note: As mentioned before, UpsertItemAsync can also be used for updates. If you call UpsertItemAsync with the id of an existing item, it will be replaced.
Delete: DeleteItemAsync
Finally, to remove an item, you use DeleteItemAsync. Like a point read, this operation is most efficient when you provide both the item's id and its partitionKey.
.NET 8 💥 - Create CRUD with Cosmos DB - Step by Step
This final piece of the repository implementation shows how to delete an item.
Watch the Delete implementation from the Delete method. The key method is _container.DeleteItemAsync<Driver>(id, new PartitionKey(team)).
4. Exposing Operations and Testing
With the repository fully implemented, the final step is to create an API controller that exposes these methods as HTTP endpoints and then test them. Given your experience, this part will be very straightforward. The video demonstrates this using a standard ApiController and testing the endpoints via the integrated Swagger UI.
.NET 8 💥 - Create CRUD with Cosmos DB - Step by Step
This final part connects the repository to a controller and tests the full application.
You can watch from the controller setup to see how the repository is injected and the endpoints are defined. Then, watch the demonstration of testing each endpoint using Swagger UI from the testing segment.
As you develop and test locally, the Azure Cosmos DB Emulator is an invaluable tool. It allows you to run a local version of the service, so you can see the items being created, updated, and deleted without incurring any costs.

Conclusion
In this lesson, you've learned the fundamental programming model for interacting with data in Azure Cosmos DB using the .NET SDK. By building a complete Web API, you've seen how these operations fit into a real-world application architecture.
Here are the key takeaways:
- The
Containerclass is your gateway for all item-level operations in Cosmos DB. - The primary methods for CRUD are
CreateItemAsync,ReadItemAsync,ReplaceItemAsync, andDeleteItemAsync. UpsertItemAsyncis a versatile alternative for both creating and updating items.- Point operations (
ReadItemAsync,DeleteItemAsync, etc.) are most efficient and require both the itemidandpartitionKey. - For retrieving multiple items, you use
GetItemQueryIteratorto execute a SQL query and process paginated results.
In our next lesson, we will explore a more advanced data manipulation technique: writing and executing stored procedures in Cosmos DB. These allow you to perform transactional operations on items within the same logical partition directly on the database server.