This is for those that need to start getting productive within Cosmos DB in a hurry. There’s a lot that could be discussed, but I think you’ll first want to be able to setup a local development environment and get to writing data to it, and reading that data. In this walkthrough, I’ll show how to make a connection to your local/development instance of Cosmos DB. Configuring a production connection is a little more involved. If you are trying to get started, that isn’t an immediate concern. I won’t cover it here. I’ve focused specifically on C# instead of targeting multiple languages to keep this shorter. Let’s get started. You need to first install the Cosmos DB emulator.
Installing the Cosmos DB Emulator
You can download the Cosmo DB Emulator from Microsoft at this address: https://aka.ms/cosmosdb-emulator. You can start the emulator from the command line. For ease of starting it, I would suggest adding the program’s path to your path environment variable. Once installed and the path updated, you can start the Cosmo DB Emulator with the following command.
Microsoft.Azure.Cosmos.Emulator.exe
By default, it will run on port 8081. If you would like to run this on a different port, use the /port=[port number] parameter. Once the emulator is running, you can the contents of the emulator at the URL https://localhost:8081/_explorer/index.html. This view will show you information for connecting to the emulator instance. Note that the information shown here will be the same on every computer on which you run this. The emulator is only for testing and not for production. The emulator accepts communication over TLS. For this purpose, the installation of emulator also resulted in the installation of a development certificate for encrypting the TLS traffic.
Create a new project and either use the package manager to add a reference to Microsoft.Azure.Cosmos. If you are using the command line to manage your project, from your project directory use the following command.
dotnet add package Microsoft.Azure.Cosmos
Creating the Database and Container in C#
With that in place, we can get into the code. start by adding a using statement for the code.
using Microsoft.Azure.Cosmos;
There are a few objects that we need to create. We need to create a client object for connecting to the database, the database object itself, and containers within the database. If you are familiar with traditional databases, then containers are similar to table. When we create the container, the values put in it will have an identifier value in a field named id. We also identify a field on which the data will be logically grouped/partitioned. For my example, I’m using an employee database and am parittioning on the department to which someone is assigned. The partition key identifier is expressed in what looks like a file path. But insted of a path in nested folders, this would be a field in what could be nested objects. If the partition key is at the root of the object, then this path will look like a file path to a file that is in the root directory.
For our local test, we will be using a resource key that is the default for any local instance of the Cosmos DB service. We would **not** be using this in a production environment. But for our local tests, it is fine.
const string RESOURCE_TOKEN = "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==";
using CosmosClient client = new(accountEndpoint: "https://localhost:6061", authKeyOrResourceToken: RESOURCE_TOKEN);
Database database = await client.CreateDatabaseIfNotExistsAsync("employeeDatabase");
Container employeeContainer = await database.CreateContainerIfNotExistsAsync("employeeContainer", "/id");
If we run the above vode and then open our browser to the Cosmos DB explorer, we will find that there’s a new container named employeeContainer. Though, there is no data in it.
Adding an Item to the Container
We could add an item to the table with only one or two more statements of code. To put an object into the container, we can create and initialize an object. Then we UpSert it into the database.
var item = new Employee()
{
ID = Guid.NewGuid(),
Name = "Joel Johnson"
};
await employeeContainer.UpsertItemAsync(item);
Now if we run the code and look in the Cosmos DB explorer, we will see our item. In addition to the fields from the public elements of our object, there are some additional fields prefixed with an underscore (_) that have additional metadata on our object, such as the time stamp (_ts) and etag (_etag).
Reading an Item from the Container
If we wanted to retrieve a specific item from the container and we know its id value and partition key value, we can use the ReadItemAsync<T> method on the container to retrieve the item. This method will deserialize the contents and return our data as an object.
var readValue = await employeeContainer.ReadItemAsync<Employee>(
id: idvalue.ToString(),
partitionKey: new PartitionKey("IT"));
We could also read the item as a stream. Readin gthe item this way will result in all the data associated with the item being read, including the fields that have additional metadata.
var readValue = await employeeContainer.ReadItemAsync<Employee>(
id: idvalue.ToString(),
partitionKey: new PartitionKey("IT"));
var itemStream = await employeeContainer.ReadItemStreamAsync(
id: idvalue.ToString(),
partitionKey: new PartitionKey("IT")
);
using ( StreamReader readItemStreamReader = new StreamReader(itemStream.Content))
{
string content = await readItemStreamReader.ReadToEndAsync();
Console.WriteLine(content);
}
Querying an Item
You probably don’t know the exact ID of the valu(s) that you want to read. But you may know something about other data for items you want. Ironically, while Cosmo DB is a “NoSQL Database”, it supports queryign with SQL.
using FeedIterator<Employee> feedIterator = employeeContainer.GetItemQueryIterator<Employee>(
queryText: "SELECT * FROM c WHERE c.dept = 'IT'");
while(feedIterator.HasMoreResults)
{
FeedResponse<Employee> response = await feedIterator.ReadNextAsync();
foreach(Employee employee in response)
{
Console.WriteLine($"Found item {employee}");
}
}
You wouldn’t want your code to be vulnerable to SQL injection attacks. If a parameter could vary, you don’t want to construct a string. You want to pass the value as parameterized input. In the SQL query, named parameters are prefiexed with the @ symbol. In the above, if we wanted to pass the department as a parameter instead of embedding it in the query, we would use code like the following.
QueryDefinition query = new QueryDefinition("SELECT * FROM c WHERE c.dept = @dept")
.WithParameter("@dept", "IT");
using FeedIterator<Employee> feedIterator = employeeContainer.GetItemQueryIterator<Employee>(query);
If you are familiar with LINQ, you could also use that to query information also. The container’s GetItemLinqQuerable<T>() method returns an object that you can use for LINQ queries.
var employeeLinqContainer = employeeContainer.GetItemLinqQueryable<Employee>(allowSynchronousQueryExecution: true );
var employeeQuery = employeeLinqContainer
.Where(e => e.Department == "IT")
.Where(e => e.DateOfBirth > new DateTime(1970, 01, 01))
.OrderBy(e => e.Name);
foreach(var employee in employeeQuery)
{
Console.WriteLine($"Found item {employee}");
}
I hope that this was enough to get you started!
Posts may contain products with affiliate links. When you make purchases using these links, we receive a small commission at no extra cost to you. Thank you for your support.
Mastodon: @j2inet@masto.ai
Instagram: @j2inet
Facebook: @j2inet
YouTube: @j2inet
Telegram: j2inet
Twitter: @j2inet


