> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Working With Microsoft NET SDK for Azure Cosmos DB

> Guide to using the Microsoft .NET SDK with Azure Cosmos DB, demonstrating client initialization, container access, CRUD operations, paged queries, and bulk data import

Working with the Microsoft .NET SDK for Azure Cosmos DB

This guide demonstrates common patterns for working with Azure Cosmos DB using the Microsoft .NET SDK: initializing a client, accessing a container, creating/upserting items, reading a single item, and querying multiple items. Each code snippet shows the typical sequence of operations and is accompanied by notes and portal screenshots for context.

Quick overview — common steps:

* Initialize a `CosmosClient` with your account endpoint and key.
* Get a `Container` reference for the target database and container.
* Create or upsert items (`CreateItemAsync`, `UpsertItemAsync`).
* Read a single item by `id` and partition key (`ReadItemAsync<T>`).
* Query items with SQL-like queries via `GetItemQueryIterator<T>` (returns a `FeedIterator<T>`).

Table: common SDK operations

| Operation | Purpose | Example method |
| - | -: | - |
| Initialize client | Connect to Cosmos DB account | `new CosmosClient(endpoint, key)` |
| Get container | Reference DB and container | `client.GetContainer(databaseName, containerName)` |
| Create item | Insert a new document | `container.CreateItemAsync(item)` |
| Upsert item | Insert or update (idempotent write) | `container.UpsertItemAsync(item)` |
| Read item | Fetch by id and partition key | `container.ReadItemAsync<T>(id, partitionKey)` |
| Query items | Execute SQL-like queries with paging | `container.GetItemQueryIterator<T>(query)` |

References:

* [Azure Cosmos DB .NET SDK documentation](https://learn.microsoft.com/azure/cosmos-db/sdk/dotnet/)
* [Azure Cosmos DB overview](https://learn.microsoft.com/azure/cosmos-db/introduction)
* [Data Migration Tool (GitHub)](https://github.com/Azure/azure-documentdb-datamigrationtool)

***

## Create items

Start by creating a `CosmosClient` and obtaining the `Container` object for the database and container where you'll store documents. The following example shows:

* Initializing the client and container.
* Defining a simple `Employee` POCO.
* Creating an item with `CreateItemAsync`.
* Demonstrating `UpsertItemAsync` (insert-or-update).

```csharp theme={null}
using System;
using System.Threading.Tasks;
using Microsoft.Azure.Cosmos;

public class Employee
{
    public string id { get; set; }
    public string name { get; set; }
    public string department { get; set; }
    public bool isFullTime { get; set; }
    public int salary { get; set; }
    public int yearsOfExperience { get; set; }
}

class Program
{
    static async Task Main(string[] args)
    {
        string endpoint = "https://<your-cosmosdb-account>.documents.azure.com:443/";
        string key = "<your-cosmosdb-account-key>";
        string databaseName = "<your-database-name>";
        string containerName = "<your-container-name>";

        CosmosClient client = new CosmosClient(endpoint, key);
        Container container = client.GetContainer(databaseName, containerName);

        Employee employeeRecord = new Employee
        {
            id = "123e4567-e89b-12d3-a456-426614174000",
            name = "John Doe",
            department = "Human Resources",
            isFullTime = true,
            salary = 4500,
            yearsOfExperience = 5
        };

        try
        {
            // Create a new item
            ItemResponse<Employee> createResponse = await container.CreateItemAsync(employeeRecord);
            Console.WriteLine($"Created item with RU charge: {createResponse.RequestCharge}");

            // Upsert (insert or update)
            ItemResponse<Employee> upsertResponse = await container.UpsertItemAsync(employeeRecord);
            Console.WriteLine($"Upserted item with RU charge: {upsertResponse.RequestCharge}");
        }
        catch (CosmosException ex)
        {
            Console.WriteLine($"Cosmos DB error: {ex.StatusCode} - {ex.Message}");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"General error: {ex.Message}");
        }
    }
}
```

<Callout icon="warning" color="#FF6B6B">
  If your container uses a partition key other than `id`, include it when creating or upserting items so the SDK routes the write correctly. Example: `await container.CreateItemAsync(employeeRecord, new PartitionKey(employeeRecord.department));`
</Callout>

Notes:

* `UpsertItemAsync` is useful for idempotent writes — it inserts if the `id` is new, or replaces the existing item if the `id` exists.
* Monitor `RequestCharge` from responses to understand RU consumption and tune throughput.

***

## Read a single item

Reading an item requires the item's `id` and its partition key value (if the container uses one). Use `ReadItemAsync<T>` to fetch a single document and access the resource via `ItemResponse<T>.Resource`.

```csharp theme={null}
using System;
using System.Threading.Tasks;
using Microsoft.Azure.Cosmos;

class Program
{
    static async Task Main(string[] args)
    {
        string endpoint = "https://<your-cosmosdb-account>.documents.azure.com:443/";
        string key = "<your-cosmosdb-account-key>";
        string databaseName = "<your-database-name>";
        string containerName = "<your-container-name>";

        CosmosClient client = new CosmosClient(endpoint, key);
        Container container = client.GetContainer(databaseName, containerName);

        string id = "123e4567-e89b-12d3-a456-426614174000";
        PartitionKey partitionKey = new PartitionKey("Human Resources");

        try
        {
            ItemResponse<Employee> response = await container.ReadItemAsync<Employee>(id, partitionKey);
            Employee item = response.Resource;
            Console.WriteLine($"Employee name: {item.name}, Department: {item.department}");
        }
        catch (CosmosException ex) when (ex.StatusCode == System.Net.HttpStatusCode.NotFound)
        {
            Console.WriteLine("Item not found.");
        }
        catch (CosmosException ex)
        {
            Console.WriteLine($"Cosmos DB error: {ex.StatusCode} - {ex.Message}");
        }
    }
}
```

***

## Query multiple items (paged queries with FeedIterator)

To query many documents, use SQL-like syntax with `GetItemQueryIterator<T>`. The method returns a `FeedIterator<T>` that yields `FeedResponse<T>` batches — which enables efficient paging through large result sets.

```csharp theme={null}
using System;
using System.Threading.Tasks;
using Microsoft.Azure.Cosmos;

class Program
{
    static async Task Main(string[] args)
    {
        string endpoint = "https://<your-cosmosdb-account>.documents.azure.com:443/";
        string key = "<your-cosmosdb-account-key>";
        string databaseName = "<your-database-name>";
        string containerName = "<your-container-name>";

        CosmosClient client = new CosmosClient(endpoint, key);
        Container container = client.GetContainer(databaseName, containerName);

        FeedIterator<dynamic> iterator = container.GetItemQueryIterator<dynamic>(
            "SELECT * FROM c WHERE c.isFullTime = true"
        );

        while (iterator.HasMoreResults)
        {
            FeedResponse<dynamic> batch = await iterator.ReadNextAsync();
            foreach (var item in batch)
            {
                Console.WriteLine($"{item.name} - {item.department}");
            }
        }
    }
}
```

This approach scales because the SDK retrieves pages of results from the service and you can process each page independently.

***

## Creating a database and container in the Azure portal

If you don't yet have a database and container, use the Azure portal Data Explorer to create them. The portal's Overview page shows account essentials and quick access to Data Explorer.

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/4asMmWJpkl1BXMJG/images/AZ-204-Developing-Solutions-for-Microsoft-Azure/Working-With-Azure-Cosmos-DB/Working-With-Microsoft-NET-SDK-for-Azure-Cosmos-DB/azure-portal-cosmosdb-overview-az204cosmosdb01.jpg?fit=max&auto=format&n=4asMmWJpkl1BXMJG&q=85&s=d19aa1d6539d3610241fe0ffaf03a49f" alt="A screenshot of the Microsoft Azure portal showing the Overview page for an Azure Cosmos DB account named &#x22;az204cosmosdb01.&#x22; The page displays account essentials (status, read/write locations, throughput), monitoring charts, and a left-hand navigation menu with options like Activity log, Tags, and Data Explorer." width="1920" height="1080" data-path="images/AZ-204-Developing-Solutions-for-Microsoft-Azure/Working-With-Azure-Cosmos-DB/Working-With-Microsoft-NET-SDK-for-Azure-Cosmos-DB/azure-portal-cosmosdb-overview-az204cosmosdb01.jpg" />
</Frame>

When creating a new container in the portal you configure:

* Database id (create new or use existing).
* Provisioned throughput (RU/s) or serverless/free options.
* Container id and partition key path (for scale and routing).
* Indexing policy and any unique keys.

Below is the New Container dialog in the Data Explorer.

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/4asMmWJpkl1BXMJG/images/AZ-204-Developing-Solutions-for-Microsoft-Azure/Working-With-Azure-Cosmos-DB/Working-With-Microsoft-NET-SDK-for-Azure-Cosmos-DB/azure-cosmosdb-new-container-form.jpg?fit=max&auto=format&n=4asMmWJpkl1BXMJG&q=85&s=a00fb17449ce8932195e8033d0a7bc0a" alt="A screenshot of the Azure Cosmos DB web portal showing the &#x22;Welcome to Azure Cosmos&#x22; home page with tiles like &#x22;Launch quick start&#x22; and &#x22;New Container.&#x22; A right-side pane is open to the &#x22;New Container&#x22; creation form, showing fields for Container id, indexing, and partition key." width="1920" height="1080" data-path="images/AZ-204-Developing-Solutions-for-Microsoft-Azure/Working-With-Azure-Cosmos-DB/Working-With-Microsoft-NET-SDK-for-Azure-Cosmos-DB/azure-cosmosdb-new-container-form.jpg" />
</Frame>

***

## Bulk loading sample data (Data Migration Tool)

For test datasets or bulk imports, use the Cosmos DB Data Migration Tool (DMT). It supports sources such as JSON files, Amazon S3, and Azure Blob Storage and sinks including Cosmos DB (NoSQL). See the GitHub repository: [https://github.com/Azure/azure-documentdb-datamigrationtool](https://github.com/Azure/azure-documentdb-datamigrationtool).

Sample migration settings for a JSON source to a Cosmos DB sink:

```json theme={null}
{
  "Source": "JSON",
  "Sink": "Cosmos-nosql",
  "SourceSettings": {
    "FilePath": "/Users/yourusername/Downloads/airports.json"
  },
  "SinkSettings": {
    "ConnectionString": "AccountEndpoint=https://<your-cosmosdb-account>.documents.azure.com:443/;AccountKey=<your-account-key>",
    "Database": "datamigration",
    "Container": "btcdata",
    "PartitionKeyPath": "/id",
    "RecreateContainer": false,
    "IncludeMetadataFields": false
  }
}
```

Example terminal steps to prepare and run the tool:

```bash theme={null}
# Navigate to the Data Migration Tool folder
cd ~/Documents/Cosmos\ DB\ DMT

# List files
ls -l

# Clear or replace migrationsettings.json
echo "" > migrationsettings.json

# Edit migrationsettings.json and run the Data Migration Tool with your settings
```

Sample logs from a successful import (example output):

```console theme={null}
info: JsonFileSource[0]
      Reading file '/Users/yourusername/Downloads/airports.json'
info: CosmosDataSinkExtension[0]
      500 records added after 4.95s (100 records/s)
info: CosmosDataSinkExtension[0]
      1000 records added after 8.11s (123 records/s)
info: CosmosDataSinkExtension[0]
      Added 1000 total records in 8.11s (123 records/s)
info: Cosmos.DataTransfer.Core.RunCommand.CommandHandler[0]
      Data transfer complete
```

A sample document ingested into the container might look like:

```json theme={null}
{
  "id": "60886968-4e2b-463d-924d-574c72e9be91",
  "airport_code": "AIM",
  "airport_name": "Ailuk Airport",
  "country_code": "Philippines",
  "_rid": "MncmAImgwm4BAAAAAAAAA==",
  "_self": "dbs/MncmAA==/colls/MncmAImgwm4=/docs/MncmAImgwm4=/",
  "_etag": "\"6b007d9b-0000-0300-0000-66ddde2c0000\"",
  "_attachments": "attachments/",
  "_ts": 1725816364
}
```

After import, validate and query documents from Data Explorer using SQL queries.

***

## Visual Studio: adding, reading, and querying items from .NET

Create a Console application and add the `Microsoft.Azure.Cosmos` NuGet package. Use the account URI and primary key from the Azure portal Keys blade to configure `CosmosClient`. Do not hard-code secrets in production—use managed identities and Azure Key Vault.

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/4asMmWJpkl1BXMJG/images/AZ-204-Developing-Solutions-for-Microsoft-Azure/Working-With-Azure-Cosmos-DB/Working-With-Microsoft-NET-SDK-for-Azure-Cosmos-DB/azure-portal-cosmosdb-keys-az204cosmosdb01.jpg?fit=max&auto=format&n=4asMmWJpkl1BXMJG&q=85&s=bff74300acc9f270805ffc910b37834b" alt="A screenshot of the Microsoft Azure portal showing the Keys page for an Azure Cosmos DB account named &#x22;az204cosmosdb01,&#x22; with the account URI, primary/secondary keys, and connection strings displayed (keys masked). The portal's left navigation and account settings are visible." width="1920" height="1080" data-path="images/AZ-204-Developing-Solutions-for-Microsoft-Azure/Working-With-Azure-Cosmos-DB/Working-With-Microsoft-NET-SDK-for-Azure-Cosmos-DB/azure-portal-cosmosdb-keys-az204cosmosdb01.jpg" />
</Frame>

<Callout icon="lightbulb" color="#1CB2FE">
  Do not store keys or secrets in source code for production. Use managed identities with Key Vault or other secure secret storage.
</Callout>

Example: inserting an airport record using an anonymous object that matches your JSON schema:

```csharp theme={null}
using System;
using System.Threading.Tasks;
using Microsoft.Azure.Cosmos;

class Program
{
    static async Task Main(string[] args)
    {
        string endpoint = "https://<your-cosmosdb-account>.documents.azure.com:443/";
        string key = "<your-cosmosdb-account-key>";
        string databaseName = "flightDetails";
        string containerName = "airportCodes";

        CosmosClient client = new CosmosClient(endpoint, key);
        Container container = client.GetContainer(databaseName, containerName);

        var airportRecord = new
        {
            id = Guid.NewGuid().ToString(),
            airport_code = "DXB",
            airport_name = "Dubai International Airport",
            country_code = "AE"
        };

        try
        {
            ItemResponse<dynamic> response = await container.CreateItemAsync(airportRecord);
            Console.WriteLine($"Inserted airport {airportRecord.airport_code}. RU charge: {response.RequestCharge}");
        }
        catch (CosmosException ex)
        {
            Console.WriteLine($"Cosmos DB error: {ex.StatusCode} - {ex.Message}");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"General error: {ex.Message}");
        }
    }
}
```

Validate the inserted record in Data Explorer with a SQL query such as:

```sql theme={null}
SELECT * FROM c WHERE c.country_code = 'AE'
```

***

## Querying by country\_code (example)

If your documents use a `country_code` property, filter by that property in your SQL query. The sample below shows querying airports by `country_code` and printing each airport name.

```csharp theme={null}
using System;
using System.Threading.Tasks;
using Microsoft.Azure.Cosmos;

class Program
{
    static async Task Main(string[] args)
    {
        string endpoint = "https://<your-cosmosdb-account>.documents.azure.com:443/";
        string key = "<your-cosmosdb-account-key>";
        string databaseName = "flightDetails";
        string containerName = "airportCodes";

        CosmosClient client = new CosmosClient(endpoint, key);
        Container container = client.GetContainer(databaseName, containerName);

        FeedIterator<dynamic> iterator = container.GetItemQueryIterator<dynamic>(
            "SELECT * FROM c WHERE c.country_code = 'United States'"
        );

        while (iterator.HasMoreResults)
        {
            FeedResponse<dynamic> batch = await iterator.ReadNextAsync();
            foreach (var airport in batch)
            {
                Console.WriteLine($"{airport.airport_name}");
            }
        }
    }
}
```

Sample console output (truncated):

```text theme={null}
Burgos Airport
Gregorio Luperon International Airport
Zvartnots International Airport
Caye Caulker Airport
Parry Sound Area Municipal Airport
Pompano Beach Airport
Akron Canton Regional Airport
Susanville Municipal Airport
Mogilev Airport
```

***

This lesson covered the essential CRUD and query patterns for using the Microsoft .NET SDK with Azure Cosmos DB. From here you can expand into partition key design, throughput tuning (RU/s), bulk imports, change feed processing, and server-side programming (stored procedures, triggers, and UDFs).

Further reading and resources:

* [Azure Cosmos DB .NET SDK quickstart](https://learn.microsoft.com/azure/cosmos-db/sql/create-sql-api-dotnet)
* [Designing partition keys](https://learn.microsoft.com/azure/cosmos-db/partitioning-overview)
* [Throughput & RU/s guidance](https://learn.microsoft.com/azure/cosmos-db/request-units)

<CardGroup>
  <Card title="Watch Video" icon="video" cta="Learn more" href="https://learn.kodekloud.com/user/courses/az-204-developing-solutions-for-microsoft-azure/module/9b20db07-78f4-4774-8a8c-8c2c182ebd0e/lesson/fa7aed3c-57f1-4c09-830f-ad374dad493b" />
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.