using System.Threading.Tasks;
using System.Collections.Generic;
using Microsoft.Azure.Cosmos;
using Microsoft.Azure.Cosmos.Linq;
static CustomerRepository _customerRepository;
public static async Task Main()
var cosmosDbConfig = new CosmosDbConfig()
EndpointUri = "https://dotnetfiddle-cosmosdb-example.documents.azure.com:443/",
Key = "fnLEDUUkIpQAmjPqL34VpXGh4zsqdHN0doj29E6vm02NxI8gsv6mXjrDhF2Fg0ypOh5jUOwdr605auqoxO3JRg==",
DatabaseName = "dotnetfiddle-cosmosdb-example-db"
_customerRepository = new CustomerRepository(cosmosDbConfig);
await RunTests(entitySize: 10);
await RunTests(entitySize: 1000);
await RunTests(entitySize: 100000);
public static async Task RunTests(int entitySize)
Console.WriteLine("=========================================");
Console.WriteLine("RunTests entitySize: ≈ " + entitySize + " bytes");
await _customerRepository.DeleteAll();
var customer = BuildCustomer(1, entitySize);
await _customerRepository.Create(customer);
var customerId = customer.Id;
var customerFromDb = await _customerRepository.GetById(customerId);
await _customerRepository.Update(customer);
await _customerRepository.Delete(customer);
Console.WriteLine("Create 10");
for (int index = 1; index <= 10; index++)
var tempCustomer = BuildCustomer(index, entitySize);
await _customerRepository.Create(tempCustomer, false);
var customers = await _customerRepository.FindAll();
Console.WriteLine("FindAll".PadRight(20) + "Count: " + customers.Count());
await _customerRepository.DeleteAll();
private static Customer BuildCustomer(int index = 1, int notesSize = 0)
notes = new string('*', notesSize);
var customer = new Customer
FirstName = "FN_" + index,
LastName = "LN_" + index,
public string Id { get; set; }
public class Customer : EntityBase
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public string Notes { get; set; }
public class CosmosDbConfig
public string EndpointUri { get; set; }
public string Key { get; set; }
public string DatabaseName { get; set; }
public class CustomerRepository : CosmosDbRepository<Customer>
protected override string ContainerName => "Customers";
public CustomerRepository(CosmosDbConfig config) : base(config)
protected override string GetPartitionKeyValue(Customer entity)
public async Task<Customer> GetById(string id)
return await base.GetById(id, partitionKeyValue: id);
public abstract class CosmosDbRepository<T> where T : EntityBase
protected abstract string ContainerName { get; }
private CosmosClient _cosmosClient;
private Container _container;
public CosmosDbRepository(CosmosDbConfig config)
_cosmosClient = new CosmosClient(config.EndpointUri, config.Key);
_container = _cosmosClient.GetContainer(config.DatabaseName, this.ContainerName);
protected abstract string GetPartitionKeyValue(T entity);
public async Task<T> Create(T entity, bool showLog = true)
entity.Id = Guid.NewGuid().ToString();
var partitionKey = new PartitionKey(GetPartitionKeyValue(entity));
var response = await _container.CreateItemAsync<T>(entity, partitionKey);
WriteCost($"Create", response.RequestCharge);
public async Task<List<T>> FindAll()
var query = CreateQuery();
return await Find(query);
protected IQueryable<T> CreateQuery()
var query = _container.GetItemLinqQueryable<T>();
protected async Task<List<T>> Find(IQueryable<T> query, bool showLog = true)
Console.WriteLine("Find".PadRight(20) + "Query: " + GetQuerySql(query));
var feedIterator = query.ToFeedIterator();
var results = new List<T>();
while (feedIterator.HasMoreResults)
var response = await feedIterator.ReadNextAsync();
WriteCost("Find", response.RequestCharge);
results.AddRange(response.ToList());
private void WriteCost(string callInfo, double cost)
Console.WriteLine($"{callInfo}".PadRight(20) + $"{cost} RU");
private string GetQuerySql(IQueryable<T> query)
sql = query.ToQueryDefinition().QueryText;
catch (ArgumentNullException)
sql = "SELECT VALUE root FROM root";
protected async Task<T> GetById(string id, string partitionKeyValue)
var partitionKey = new PartitionKey(partitionKeyValue);
var response = await _container.ReadItemAsync<T>(id, partitionKey);
WriteCost($"GetById", response.RequestCharge);
return response.Resource;
public async Task Update(T entity)
var partitionKey = new PartitionKey(GetPartitionKeyValue(entity));
var response = await _container.UpsertItemAsync<T>(entity, partitionKey);
WriteCost($"Update", response.RequestCharge);
public async Task Delete(T entity)
var partitionKey = new PartitionKey(GetPartitionKeyValue(entity));
var response = await _container.DeleteItemAsync<T>(entity.Id, partitionKey);
WriteCost($"Delete", response.RequestCharge);
public async Task DeleteAll()
var query = CreateQuery();
var entities = await Find(query, false);
foreach (var entity in entities)
var partitionKeyValue = GetPartitionKeyValue(entity);
await _container.DeleteItemAsync<T>(entity.Id, new PartitionKey(partitionKeyValue));
Console.WriteLine("\nDelete All\n");