CAST supports Azure Cosmos DB via its NoSQL for .NET extension. Details about how this support is provided for .NET source code is discussed below.

Supported Client Libraries

(tick)
Azure Cosmos DB .NET SDK 3.x for SQL API (tick)
CosmonautClient(tick)

Supported Operations

OperationMethods Supported
Create


  • Microsoft.Azure.Documents.Client.DocumentClient.CreateDocumentCollectionAsync
  • Microsoft.Azure.Documents.IDocumentClient.CreateDocumentCollectionAsync
  • Microsoft.Azure.Documents.Client.DocumentClient.CreateDocumentCollectionIfNotExistsAsync
  • Microsoft.Azure.Documents.IDocumentClient.CreateDocumentCollectionIfNotExistsAsync


  • Microsoft.Azure.Cosmos.Fluent.ContainerBuilder.CreateIfNotExistsAsync
  • Microsoft.Azure.Cosmos.Fluent.ContainerBuilder.CreateAsync
  • Microsoft.Azure.Cosmos.Database.CreateContainerIfNotExistsAsync
  • Microsoft.Azure.Cosmos.CosmosDatabase.CreateContainerIfNotExistsAsync
  • Microsoft.Azure.Cosmos.Database.GetContainer
  • Microsoft.Azure.CosmosDatabase.GetContainer
  • Microsoft.Azure.Cosmos.CosmosClient.GetContainer
  • Microsoft.Azure.Cosmos.Database.CreateContainerStreamAsync
  • Microsoft.Azure.CosmosDatabase.CreateContainerStreamAsync


  • Cosmonaut.CosmonautClient.CreateCollectionAsync 
  • Cosmonaut.ICosmonautClient.CreateCollectionAsync
  • Cosmonaut.CosmonautClient.GetCollectionAsync
  • Cosmonaut.ICosmonautClient.GetCollectionAsync


Insert


  • Microsoft.Azure.Documents.Client.DocumentClient.CreateDocumentAsync

  • Microsoft.Azure.Documents.IDocumentClient.CreateDocumentAsync
  • Microsoft.Azure.Documents.Client.DocumentClient.UpsertDocumentAsync
  • Microsoft.Azure.Documents.IDocumentClient.UpsertDocumentAsync


  • Microsoft.Azure.Cosmos.Container.CreateItemAsync
  • Microsoft.Azure.CosmosContainer.CreateItemAsync
  • Microsoft.Azure.Cosmos.Container.CreateItemStreamAsync
  • Microsoft.Azure.CosmosContainer.CreateItemStreamAsync
  • Microsoft.Azure.Cosmos.Container.UpsertItemAsync
  • Microsoft.Azure.Cosmos.Container.UpsertItemStreamAsync


  • Cosmonaut.CosmonautClient.CreateDocumentAsync
  • Cosmonaut.ICosmonautClient.CreateDocumentAsync
  • Cosmonaut.CosmonautClient.UpsertDocumentAsync
  • Cosmonaut.ICosmonautClient.UpsertDocumentAsync


Update


  • Microsoft.Azure.Documents.Client.DocumentClient.ReplaceDocumentAsync
  • Microsoft.Azure.Documents.IDocumentClient.ReplaceDocumentAsync
  • Microsoft.Azure.Documents.Client.DocumentClient.ReplaceDocumentCollectionAsync
  • Microsoft.Azure.Documents.IDocumentClient.ReplaceDocumentCollectionAsync
  • Microsoft.Azure.Documents.Client.DocumentClient.UpsertDocumentAsync
  • Microsoft.Azure.Documents.IDocumentClient.UpsertDocumentAsync


  • Microsoft.Azure.Cosmos.Container.ReplaceItemAsync
  • Microsoft.Azure.Cosmos.Container.ReplaceItemStreamAsync
  • Microsoft.Azure.Cosmos.Container.ReplaceContainerAsync
  • Microsoft.Azure.CosmosContainer.ReplaceContainerStreamAsync
  • Microsoft.Azure.Cosmos.Container.ReplaceContainerStreamAsync
  • Microsoft.Azure.Cosmos.Container.UpsertItemAsync
  • Microsoft.Azure.Cosmos.Container.UpsertItemStreamAsync


  • Cosmonaut.CosmonautClient.UpdateDocumentAsync
  • Cosmonaut.ICosmonautClient.UpdateDocumentAsync
  • Cosmonaut.CosmonautClient.UpdateCollectionAsync
  • Cosmonaut.ICosmonautClient.UpdateCollectionAsync
  • Cosmonaut.CosmonautClient.UpsertDocumentAsync 
  • Cosmonaut.ICosmonautClient.UpsertDocumentAsync


Select


  • Microsoft.Azure.Documents.Client.DocumentClient.ReadDocumentAsync
  • Microsoft.Azure.Documents.IDocumentClient.ReadDocumentAsync
  • Microsoft.Azure.Documents.Client.DocumentClient.ReadDocumentCollectionAsync
  • Microsoft.Azure.Documents.IDocumentClient.ReadDocumentCollectionAsync
  • Microsoft.Azure.Documents.Client.DocumentClient.CreateDocumentQuery
  • Microsoft.Azure.Documents.Client.DocumentClient.CreateDocumentQuery


  • Microsoft.Azure.Cosmos.Container.ReadItemAsync
  • Microsoft.Azure.CosmosContainer.ReadItemStreamAsync
  • Microsoft.Azure.Cosmos.Container.ReadItemStreamAsync
  • Microsoft.Azure.Cosmos.Container.ReadContainerStreamAsync
  • Microsoft.Azure.CosmosContainer.ReadContainerStreamAsync


  • Cosmonaut.CosmonautClient.GetDocumentAsync 
  • Cosmonaut.ICosmonautClient.GetDocumentAsync


Delete


  • Microsoft.Azure.Documents.Client.DocumentClient.DeleteDocumentAsync
  • Microsoft.Azure.Documents.IDocumentClient.DeleteDocumentAsync
  • Microsoft.Azure.Documents.Client.DocumentClient.DeleteDocumentCollectionAsync
  • Microsoft.Azure.Documents.IDocumentClient.DeleteDocumentCollectionAsync


  • Microsoft.Azure.Cosmos.Container.DeleteItemAsync
  • Microsoft.Azure.CosmosContainer.DeleteItemAsync
  • Microsoft.Azure.Cosmos.Container.DeleteItemStreamAsync
  • Microsoft.Azure.Cosmos.Container.DeleteContainerAsync
  • Microsoft.Azure.CosmosContainer.DeleteContainerAsync
  • Microsoft.Azure.Cosmos.Container.DeleteContainerStreamAsync


  • Cosmonaut.CosmonautClient.DeleteDocumentAsync
  • Cosmonaut.ICosmonautClient.DeleteDocumentAsync
  • Cosmonaut.CosmonautClient.DeleteCollectionAsync
  • Cosmonaut.ICosmonautClient.DeleteCollectionAsync


Objects

IconDescription

DotNet CosmosDB Database

DotNet CosmosDB Collection

 

DotNet CosmosDB Unknown Database 

 

DotNet CosmosDB Unknown Collection 

Links

Links are created for transaction and function point needs:

Link typeWhen is this created? Methods Supported
belongsTo

From DotNet CosmosDB Collection object to DotNet CosmosDB Database object


useLinkBetween the caller .NET Method objects and DotNet CosmosDB Collection object



  • CreateDocumentCollectionAsync
  • CreateDocumentCollectionIfNotExistsAsync
  • GetContainer
  • CreateContainerIfNotExistsAsync
  • CreateContainerAsync
  • CreateIfNotExistsAsync
  • CreateAsync
  • CreateContainerStreamAsync
  • CreateCollectionAsync
  • GetCollectionAsync


useInsertLink


  • CreateDocumentAsync
  • UpsertDocumentAsync
  • CreateItemAsync
  • CreateItemStreamAsync
  • UpsertItemAsync
  • UpsertItemStreamAsync


useUpdateLink


  • ReplaceDocumentAsync
  • ReplaceDocumentCollectionAsync
  • UpsertDocumentAsync
  • ReplaceItemAsync
  • ReplaceItemStreamAsync
  • ReplaceContainerAsync
  • ReplaceContainerStreamAsync
  • UpsertItemAsync
  • UpsertItemStreamAsync
  • UpdateDocumentAsync
  • UpdateCollectionAsync


useSelectLink


  • ReadDocumentAsync
  • ReadDocumentCollectionAsync
  • CreateDocumentQuery
  • ReadItemAsync
  • ReadItemStreamAsync
  • ReadContainerAsync
  • ReadContainerStreamAsync
  • GetDocumentAsync


useDeletetLink


  • DeleteDocumentAsync
  • DeleteDocumentCollectionAsync
  • DeleteItemAsync
  • DeleteContainerAsync
  • DeleteContainerStreamAsync
  • DeleteCollectionAsync


What results can you expect?

Once the analysis/snapshot generation has completed, you can view the results in the normal manner (for example via CAST Enlighten). Some examples are shown below.

Azure Cosmos DB Database and Table Creation


private static readonly string databaseName = "samples";
private static readonly string collectionName = "document-samples";

private static async Task Initialize()
        {
            await client.CreateDatabaseIfNotExistsAsync(new Database { Id = databaseName });

            // We create a partitioned collection here which needs a partition key. Partitioned collections
            // can be created with very high values of provisioned throughput (up to OfferThroughput = 250,000)
            // and used to store up to 250 GB of data. You can also skip specifying a partition key to create
            // single partition collections that store up to 10 GB of data.
            DocumentCollection collectionDefinition = new DocumentCollection();
            collectionDefinition.Id = collectionName;

            // For this demo, we create a collection to store SalesOrders. We set the partition key to the account
            // number so that we can retrieve all sales orders for an account efficiently from a single partition,
            // and perform transactions across multiple sales order for a single account number. 
            collectionDefinition.PartitionKey.Paths.Add("/AccountNumber");

            // Use the recommended indexing policy which supports range queries/sorting on strings
            collectionDefinition.IndexingPolicy = new IndexingPolicy(new RangeIndex(DataType.String) { Precision = -1 });

            // Create with a throughput of 1000 RU/s
            await client.CreateDocumentCollectionIfNotExistsAsync(
                UriFactory.CreateDatabaseUri(databaseName),
                collectionDefinition,
                new RequestOptions { OfferThroughput = 1000 });
        }


private static async Task Initialize(CosmosClient client)
        {
            database = await client.CreateDatabaseIfNotExistsAsync(databaseId);

            ContainerProperties containerProperties = new ContainerProperties(containerId, partitionKeyPath: "/AccountNumber");

            // Create with a throughput of 1000 RU/s
            container = await database.CreateContainerIfNotExistsAsync(
                containerProperties,
                throughput: 1000);
        }


Insert Operation


private static async Task CreateDocumentsAsync()
        {
            Uri collectionUri = UriFactory.CreateDocumentCollectionUri(databaseName, collectionName);
            Console.WriteLine("\n1.1 - Creating documents");
            SalesOrder salesOrder = GetSalesOrderSample("SalesOrder1");
            await client.CreateDocumentAsync(collectionUri, salesOrder);
			SalesOrder2 newSalesOrder = GetSalesOrderV2Sample("SalesOrder2");
            await client.CreateDocumentAsync(collectionUri, newSalesOrder);
		}



private static async Task<SalesOrder> CreateItemsAsync()
        {
            Console.WriteLine("\n1.1 - Creating items");

            // Create a SalesOrder object. This object has nested properties and various types including numbers, DateTimes and strings.
            // This can be saved as JSON as is without converting into rows/columns.
            SalesOrder salesOrder = GetSalesOrderSample("SalesOrder1");
            ItemResponse<SalesOrder> response = await container.CreateItemAsync(salesOrder, new PartitionKey(salesOrder.AccountNumber));
            SalesOrder salesOrder1 = response;
            Console.WriteLine($"\n1.1.1 - Item created {salesOrder1.Id}");
		}



public async Task<DocumentStorageResponse<TEntity>> InsertAsync<TEntity>(TEntity entity, DocumentOptions options = null, CancellationToken cancellationToken = default)
        where TEntity : Entity
        {
            var response = await this.documentClient.CreateDocumentAsync(this.databaseName, this.collectionName, entity, options.ToRequestOptions(),     cancellationToken).ConfigureAwait(false);
            return response.ToDocumentStorageResponse();
        }

Select Operation


private static async Task ReadDocumentAsync()
        {
            Console.WriteLine("\n1.2 - Reading Document by Id");

            var response = await client.ReadDocumentAsync(
            	UriFactory.CreateDocumentUri(databaseName, collectionName, "SalesOrder1"), 
                new RequestOptions { PartitionKey = new PartitionKey("Account1") });
		}

private static async Task ReadDocumentCollectionAsync()
        {
            Console.WriteLine("\n1.7 - Reading a document");
            ResourceResponse<Document> response = await client.ReadDocumentCollectionAsync(
                UriFactory.CreateDocumentUri(databaseName, collectionName, "SalesOrder3"),
                new RequestOptions { PartitionKey = new PartitionKey("Account1") });
        }

private static SalesOrder QueryDocuments()
        {
            Console.WriteLine("\n1.4 - Querying for a document using its AccountNumber property");

            SalesOrder querySalesOrder = client.CreateDocumentQuery<SalesOrder>(
                UriFactory.CreateDocumentCollectionUri(databaseName, collectionName))
                .Where(so => so.AccountNumber == "Account1")
                .AsEnumerable()
                .First();

            Console.WriteLine(querySalesOrder.AccountNumber);
            return querySalesOrder;
        }


private static async Task ReadItemAsync()
        {
            Console.WriteLine("\n1.2 - Reading Item by Id");

            // Note that Reads require a partition key to be specified.
            ItemResponse<SalesOrder> response = await container.ReadItemAsync<SalesOrder>(
                partitionKey: new PartitionKey("Account1"),
                id: "SalesOrder1");
		}



public Task<TEntity> FindAsync<TEntity>(string id, DocumentOptions options = null, CancellationToken cancellationToken = default)
            where TEntity : Entity
        {
            return this.documentClient.GetDocumentAsync<TEntity>(this.databaseName, this.collectionName, id, options.ToRequestOptions(), cancellationToken);
        }

Update Operation


	private static async Task ReplaceDocumentAsync(SalesOrder order)
        {
            Console.WriteLine("\n1.5 - Replacing a document using its Id");
            order.ShippedDate = DateTime.UtcNow;
            ResourceResponse<Document> response = await client.ReplaceDocumentAsync(
                UriFactory.CreateDocumentUri(databaseName, collectionName, order.Id), 
                order);

            var updated = response.Resource;
            Console.WriteLine("Request charge of replace operation: {0}", response.RequestCharge);
            Console.WriteLine("Shipped date of updated document: {0}", updated.GetPropertyValue<DateTime>("ShippedDate"));
        }

private static async Task ReplaceDocumentCollectionAsync()
        {
            Console.WriteLine("\n1.7 - Updating a document");
            ResourceResponse<Document> response = await client.ReplaceDocumentCollectionAsync(
                UriFactory.CreateDocumentUri(databaseName, collectionName, "SalesOrder3"),
                new RequestOptions { PartitionKey = new PartitionKey("Account1") });

            Console.WriteLine("Request charge of update operation: {0}", response.RequestCharge);
            Console.WriteLine("StatusCode of operation: {0}", response.StatusCode);
        }


private static async Task ReplaceItemAsync(SalesOrder order)
        {
            Console.WriteLine("\n1.6 - Replacing a item using its Id");

            order.ShippedDate = DateTime.UtcNow;
            ItemResponse<SalesOrder> response = await container.ReplaceItemAsync(
                partitionKey: new PartitionKey(order.AccountNumber),
                id: order.Id,
                item: order);
		}


public async Task<DocumentStorageResponse<TEntity>> UpdateAsync<TEntity>(TEntity entity, DocumentOptions options = null, CancellationToken cancellationToken = default)
            where TEntity : Entity
        {
            var requestOptions = options.ToRequestOptions();
            var document = entity.ToCosmonautDocument(this.settings.JsonSerializerSettings);
            var response = await this.documentClient.UpdateDocumentAsync(this.databaseName, this.collectionName, document, requestOptions, cancellationToken)              .ExecuteCosmosCommand(entity).ConfigureAwait(false);
            return response.ToDocumentStorageResponse();
        }

Upsert Operation


private static async Task UpsertDocumentAsync()
        {
            Console.WriteLine("\n1.6 - Upserting a document");

            var upsertOrder = GetSalesOrderSample("SalesOrder3");
            ResourceResponse<Document> response = await client.UpsertDocumentAsync(UriFactory.CreateDocumentCollectionUri(databaseName, collectionName), upsertOrder);
            var upserted = response.Resource;

            Console.WriteLine("Request charge of upsert operation: {0}", response.RequestCharge);
            Console.WriteLine("StatusCode of this operation: {0}", response.StatusCode);
            Console.WriteLine("Id of upserted document: {0}", upserted.Id);
            Console.WriteLine("AccountNumber of upserted document: {0}", upserted.GetPropertyValue<string>("AccountNumber"));

            upserted.SetPropertyValue("AccountNumber", "updated account number");
            response = await client.UpsertDocumentAsync(UriFactory.CreateDocumentCollectionUri(databaseName, collectionName), upserted);
            upserted = response.Resource;

            Console.WriteLine("Request charge of upsert operation: {0}", response.RequestCharge);
            Console.WriteLine("StatusCode of this operation: {0}", response.StatusCode);
            Console.WriteLine("Id of upserted document: {0}", upserted.Id);
            Console.WriteLine("AccountNumber of upserted document: {0}", upserted.GetPropertyValue<string>("AccountNumber"));
        }


private static async Task UpsertItemAsync()
        {
            Console.WriteLine("\n1.8 - Upserting a item");

            SalesOrder upsertOrder = GetSalesOrderSample("SalesOrder3");
            
            //creates the initial SalesOrder document. 
            //notice the response.StatusCode returned indicates a Create operation was performed
            ItemResponse<SalesOrder> response = await container.UpsertItemAsync(
                partitionKey: new PartitionKey(upsertOrder.AccountNumber),
                item: upsertOrder);
		}

public async Task<DocumentStorageResponse<TEntity>> UpsertAsync<TEntity>(TEntity entity, DocumentOptions options = null, CancellationToken cancellationToken = default)
        where TEntity : Entity
        {
              var requestOptions = options.ToRequestOptions();
              var document = entity.ToCosmonautDocument(this.settings.JsonSerializerSettings);
              var response = await this.documentClient.UpsertDocumentAsync(this.databaseName, this.collectionName, document, requestOptions, cancellationToken).ExecuteCosmosCommand(entity).ConfigureAwait(false);
              return response.ToDocumentStorageResponse();
        }



Delete Operation


 private static async Task DeleteDocumentAsync()
        {
            Console.WriteLine("\n1.7 - Deleting a document");
            ResourceResponse<Document> response = await client.DeleteDocumentAsync(
                UriFactory.CreateDocumentUri(databaseName, collectionName, "SalesOrder3"),
                new RequestOptions { PartitionKey = new PartitionKey("Account1") });

            Console.WriteLine("Request charge of delete operation: {0}", response.RequestCharge);
            Console.WriteLine("StatusCode of operation: {0}", response.StatusCode);
        }

private static async Task DeleteDocumentCollectionAsync()
        {
            Console.WriteLine("\n1.7 - Deleting a document");
            ResourceResponse<Document> response = await client.DeleteDocumentCollectionAsync(
                UriFactory.CreateDocumentUri(databaseName, collectionName, "SalesOrder3"),
                new RequestOptions { PartitionKey = new PartitionKey("Account1") });

            Console.WriteLine("Request charge of delete operation: {0}", response.RequestCharge);
            Console.WriteLine("StatusCode of operation: {0}", response.StatusCode);
        }



private static async Task DeleteItemAsync()
        {
            Console.WriteLine("\n1.9 - Deleting a item");
            ItemResponse<SalesOrder> response = await container.DeleteItemAsync<SalesOrder>(
                partitionKey: new PartitionKey("Account1"),
                id: "SalesOrder3");

            Console.WriteLine("Request charge of delete operation: {0}", response.RequestCharge);
            Console.WriteLine("StatusCode of operation: {0}", response.StatusCode);
        }



public async Task<DocumentStorageResponse<TEntity>> RemoveAsync<TEntity>(string id, DocumentOptions options = null, CancellationToken cancellationToken = default)
             where TEntity : Entity
             {
                    var response = await this.documentClient.DeleteDocumentAsync(this.databaseName, this.collectionName, id, options.ToRequestOptions(), cancellationToken)
.ExecuteCosmosCommand<TEntity>(null).ConfigureAwait(false);
                    return response.ToDocumentStorageResponse();
             }



Reading App.config


private static readonly string collectionName = ConfigurationManager.AppSettings["CollectionName"];
private static readonly string database = ConfigurationManager.AppSettings["DatabaseName"];
private static void InsertDataWithDatabaseAndCollectionArgument(Family family)
{
	await this.client.CreateDocumentAsync(UriFactory.CreateDocumentCollectionUri(database, collectionName), family);

}


<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
	<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
<appSettings>
	<add key="EndPointUrl" value="https://localhost:443/" />
	<add key="AuthorizationKey" value="C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==" />
	<add key="DatabaseName" value="bulkUpdateDb" />
	<add key="CollectionName" value="bulkUpdateColl" />
	<add key="CollectionThroughput" value="100000" />
	<add key="ShouldCleanupOnStart" value="false" />
	<add key="ShouldCleanupOnFinish" value="false" />
	<add key="NumberOfDocumentsToUpdate" value="2500000" />
	<add key="NumberOfBatches" value="25" />
	<add key="CollectionPartitionKey" value="/profileid" />
</appSettings>


Evolution

Limitations