Azure Cosmos DB with ASP.NET Core
Build globally distributed applications with Azure Cosmos DB.
By EMEPublished: February 20, 2025
azure cosmos dbnosqldatabaseglobally distributedaspnet core
A Simple Analogy
Cosmos DB is like having databases in multiple cities worldwide. Users always connect to the nearest one, getting instant responses. Data automatically syncs globally, maintaining consistency.
What Is Cosmos DB?
Azure Cosmos DB is a globally distributed, multi-model database. It supports documents, key-value pairs, graphs, and time-series data with automatic replication across regions.
Why Use Cosmos DB?
- Global scale: Replicate to any region instantly
- Low latency: Read from nearest region
- Multi-model: Documents, graphs, key-value
- High availability: 99.99% SLA
- Serverless: Pay per operation, not infrastructure
.NET Implementation
using Microsoft.Azure.Cosmos;
var cosmosClient = new CosmosClient(
connectionString: "AccountEndpoint=...;AccountKey=...;",
clientOptions: new CosmosClientOptions
{
ConnectionMode = ConnectionMode.Direct
});
var container = cosmosClient.GetContainer("database", "users");
// Create document
var user = new User { Id = "user-1", Name = "Alice", Email = "alice@example.com" };
await container.CreateItemAsync(user);
// Read document
var response = await container.ReadItemAsync<User>("user-1", new PartitionKey("alice@example.com"));
var retrievedUser = response.Resource;
// Update document
user.Name = "Alice Updated";
await container.UpsertItemAsync(user);
// Query documents
var query = container.GetItemQueryIterator<User>(
"SELECT * FROM c WHERE c.Email = @email",
requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey("alice@example.com") },
parameters: new[] { new SqlParameter("@email", "alice@example.com") });
var results = new List<User>();
while (query.HasMoreResults)
{
var page = await query.ReadNextAsync();
results.AddRange(page);
}
Practical Example
public class UserRepository
{
private readonly Container _container;
public async Task<User> GetUserAsync(string userId, string email)
{
try
{
var response = await _container.ReadItemAsync<User>(
userId,
new PartitionKey(email));
return response.Resource;
}
catch (CosmosException ex) when (ex.StatusCode == System.Net.HttpStatusCode.NotFound)
{
return null;
}
}
public async Task<List<User>> SearchByEmailDomainAsync(string domain)
{
var query = _container.GetItemQueryIterator<User>(
$"SELECT * FROM c WHERE CONTAINS(c.Email, '@{domain}')"
);
var results = new List<User>();
while (query.HasMoreResults)
{
results.AddRange(await query.ReadNextAsync());
}
return results;
}
}
Partition Strategy
// Good: Use frequently-filtered field as partition key
public class User
{
[JsonProperty(PropertyName = "id")]
public string Id { get; set; }
[JsonProperty(PropertyName = "pk")] // Partition key
public string Email { get; set; } // Used for filtering
public string Name { get; set; }
}
// Query using partition key (efficient)
var response = await container.ReadItemAsync<User>(
"user-1",
new PartitionKey("alice@example.com"));
// Avoid cross-partition queries (slower, costs more)
// SELECT * FROM c WHERE c.Name = "Alice" // Avoid!
Best Practices
- Choose partition key carefully: Most frequent filter
- Use point reads: Specify partition key when possible
- Batch operations: Group writes together
- Monitor RU usage: Understand cost drivers
- Set TTL: Auto-delete old documents
Related Concepts
- Consistency levels (strong, bounded, session)
- Indexing strategies
- Change feed for replication
- Bulk operations
- Multi-region failover
Summary
Cosmos DB provides globally distributed data with low latency and high availability. Master partition keys, queries, and consistency models to build globally scalable applications.