Support of Azure Cosmos DB for .NET

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

Supported Client Libraries

Library

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

Supported Operations

Operation Scenario Methods Supported
Create Methods Supported for Create - 2.x

Microsoft.Azure.Documents.Client.DocumentClient.CreateDocumentCollectionAsync

Microsoft.Azure.Documents.IDocumentClient.CreateDocumentCollectionAsync

Microsoft.Azure.Documents.Client.DocumentClient.CreateDocumentCollectionIfNotExistsAsync

Microsoft.Azure.Documents.IDocumentClient.CreateDocumentCollectionIfNotExistsAsync

Create Methods Supported for Create - 3.x

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

Create Methods Supported for Create - CosmonautClient

Methods Supported for Create - CosmonautClient

Insert Methods Supported for Insert - 2.x

Microsoft.Azure.Documents.Client.DocumentClient.CreateDocumentAsync

Microsoft.Azure.Documents.IDocumentClient.CreateDocumentAsync

Microsoft.Azure.Documents.Client.DocumentClient.UpsertDocumentAsync

Microsoft.Azure.Documents.IDocumentClient.UpsertDocumentAsync

Insert Methods Supported for Insert - 3.x

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

Microsoft.Azure.Cosmos.Container.CreateItemAsync

Insert Methods Supported for Insert - CosmonautClient

Cosmonaut.CosmonautClient.CreateDocumentAsync

Cosmonaut.ICosmonautClient.CreateDocumentAsync

Cosmonaut.CosmonautClient.UpsertDocumentAsync

Cosmonaut.ICosmonautClient.UpsertDocumentAsync

Update Methods Supported for Update - 2.x

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

Update Methods Supported for Update - 3.x

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

Microsoft.Azure.Cosmos.Container.ReplaceThroughputAsync

Update Methods Supported for Update - CosmonautClient

Cosmonaut.CosmonautClient.UpdateDocumentAsync

Cosmonaut.ICosmonautClient.UpdateDocumentAsync

Cosmonaut.CosmonautClient.UpdateCollectionAsync

Cosmonaut.ICosmonautClient.UpdateCollectionAsync

Cosmonaut.CosmonautClient.UpsertDocumentAsync 

Cosmonaut.ICosmonautClient.UpsertDocumentAsync

Select Methods Supported for Select - 2.x

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

Select Methods Supported for Select - 3.x

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.ReadThroughputAsync

Microsoft.Azure.Cosmos.Container.ReadManyItemsStreamAsync

Microsoft.Azure.Cosmos.Container.ReadManyItemsAsync

Microsoft.Azure.Cosmos.Container.PatchItemAsync

Microsoft.Azure.Cosmos.Container.PatchItemStreamAsync

Microsoft.Azure.Cosmos.Container.GetItemQueryStreamIterator

Microsoft.Azure.Cosmos.Container.GetItemQueryIterator

Microsoft.Azure.Cosmos.Container.GetItemLinqQueryable

Microsoft.Azure.Cosmos.Container.GetFeedRangesAsync

Microsoft.Azure.Cosmos.Container.GetChangeFeedStreamIterator

Microsoft.Azure.Cosmos.Container.GetChangeFeedIterator

Microsoft.Azure.Cosmos.Container.ChangeFeedHandlerWithManualCheckpoint

Microsoft.Azure.Cosmos.Container.ChangeFeedStreamHandler

Microsoft.Azure.Cosmos.Container.ChangeFeedStreamHandlerWithManualCheckpoint

Microsoft.Azure.Cosmos.Container.ChangeFeedMonitorErrorDelegate

Microsoft.Azure.Cosmos.Container.ChangeFeedMonitorLeaseAcquireDelegate

Microsoft.Azure.Cosmos.Container.ChangeFeedMonitorLeaseReleaseDelegate

Microsoft.Azure.Cosmos.Container.GetChangeFeedProcessorBuilder

Microsoft.Azure.Cosmos.Container.GetChangeFeedProcessorBuilderWithManualCheckpoint

Microsoft.Azure.Cosmos.Container.GetPartitionKeyRangesAsync

Microsoft.Azure.Cosmos.Container.GetChangeFeedProcessorBuilderWithAllVersionsAndDeletes

Select Methods Supported for Select - CosmonautClient

Cosmonaut.CosmonautClient.GetDocumentAsync 

Cosmonaut.ICosmonautClient.GetDocumentAsync

Delete Methods Supported for Delete - 2.x

Microsoft.Azure.Documents.Client.DocumentClient.DeleteDocumentAsync

Microsoft.Azure.Documents.IDocumentClient.DeleteDocumentAsync

Microsoft.Azure.Documents.Client.DocumentClient.DeleteDocumentCollectionAsync

Microsoft.Azure.Documents.IDocumentClient.DeleteDocumentCollectionAsync

Delete Methods Supported for Delete - 3.x

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

Microsoft.Azure.Cosmos.Container.DeleteItemAsync

Microsoft.Azure.Cosmos.Container.DeleteAllItemsByPartitionKeyStreamAsync

Delete Methods Supported for Delete - CosmonautClient

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

Objects

Icon Description

DotNet CosmosDB Database

DotNet CosmosDB Collection

DotNet CosmosDB Unknown Database 

DotNet CosmosDB Unknown Collection 
Link type When is this created?  Methods Supported
belongsTo

From DotNet CosmosDB Collection object to DotNet CosmosDB Database object

-
useLink Between the caller .NET Method objects and DotNet CosmosDB Collection object


CreateDocumentCollectionAsync

CreateDocumentCollectionIfNotExistsAsync

GetContainer

CreateContainerIfNotExistsAsync

CreateContainerAsync

CreateIfNotExistsAsync

CreateAsync

CreateContainerStreamAsync

CreateCollectionAsync

GetCollectionAsync

useInsertLink

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

CreateDocumentAsync

UpsertDocumentAsync

CreateItemAsync

CreateItemStreamAsync

UpsertItemAsync

UpsertItemStreamAsync

useUpdateLink Between the caller .NET Method objects and DotNet CosmosDB Collection object

ReplaceDocumentAsync

ReplaceDocumentCollectionAsync

UpsertDocumentAsync

ReplaceItemAsync

ReplaceItemStreamAsync

ReplaceContainerAsync

ReplaceContainerStreamAsync

UpsertItemAsync

UpsertItemStreamAsync

UpdateDocumentAsync

UpdateCollectionAsync

useSelectLink Between the caller .NET Method objects and DotNet CosmosDB Collection object

ReadDocumentAsync

ReadDocumentCollectionAsync

CreateDocumentQuery

ReadItemAsync

ReadItemStreamAsync

ReadContainerAsync

ReadContainerStreamAsync

GetDocumentAsync

useDeletetLink Between the caller .NET Method objects and DotNet CosmosDB Collection object

DeleteDocumentAsync

DeleteDocumentCollectionAsync

DeleteItemAsync

DeleteContainerAsync

DeleteContainerStreamAsync

DeleteCollectionAsync

What results can you expect?

Some example scenarios are shown below.

Azure Cosmos DB Database and Table Creation

CreateDatabase and CreateCollection - 2.x

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 });
        }

Create Database and Container - 3.x

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

CreateDocumentAsync - 2.x

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);
        }

CreateItemAsync - 3.x

CreateItemAsync - 3.x

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}");
        }

CreateDocumentAsync - CosmonautClient

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

ReadDocumentAsync - 2.x

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") });
        }

ReadDocumentCollectionAsync - 2.x

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") });
        }

CreateDocumentAsync - 2.x

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;
        }

ReadItemAsync - 3.x

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");
        }

GetDocumentAsync - CosmonautClient

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

ReplaceDocumentAsync - 2.x

    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"));
        }

ReplaceCollectionDocumentAsync - 2.x

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);
        }

ReplaceItemAsync - 3.x

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);
        }

UpdateDocumentAsync - CosmonautClient

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();
        }

ReplaceItemAsync Sample

public static async Task Main(string[] args)
        {
            try
            {
                databaseId = "deviceInformation";
                containerId = "device-samples";

                IConfigurationRoot configuration = new ConfigurationBuilder()
                    .AddJsonFile("appSettings.json")
                    .Build();

                string endpoint = configuration["EndPointUrl"];
                if (string.IsNullOrEmpty(endpoint))
                {
                    throw new ArgumentNullException("Please specify a valid endpoint in the appSettings.json");
                }

                string authKey = configuration["AuthorizationKey"];
                if (string.IsNullOrEmpty(authKey) || string.Equals(authKey, "Super secret key"))
                {
                    throw new ArgumentException("Please specify a valid AuthorizationKey in the appSettings.json");
                }

                using (CosmosClient client = new CosmosClient(endpoint, authKey))
                {
                    Database database = await client.CreateDatabaseIfNotExistsAsync(databaseId);

                    // Create the container using REST API without a partition key definition
                    //await Program.CreateNonPartitionedContainerAsync(endpoint, authKey);

                    Container container = database.GetContainer(containerId);

                    // Read back the same container and verify that partition key path is populated
                    // Partition key is returned when read from V3 SDK.
                    ContainerResponse containerResposne = await container.ReadContainerAsync();
                    if (containerResposne.Resource.PartitionKeyPath != null)
                    {
                        Console.WriteLine("Container Partition Key path {0}", containerResposne.Resource.PartitionKeyPath);
                    }
                    else
                    {
                        throw new Exception("Unexpected error : Partition Key is not populated in a migrated collection");
                    }

                    Console.WriteLine("--Demo Item operations with no partition key--");
                    await Program.ItemOperationsWithNonePartitionKeyValue(container);

                    Console.WriteLine("--Demo Item operations with valid partition key--");
                    await Program.ItemOperationsWithValidPartitionKeyValue(container);

                    Console.WriteLine("--Demo migration of items inserted with no partition key to items with a partition key--");
                    await Program.MigratedItemsFromNonePartitionKeyToValidPartitionKeyValue(container);

                    // Clean up the database -- for rerunning the sample
                    await database.DeleteAsync();
                }
            }
            catch (CosmosException cre)
            {
                Console.WriteLine(cre.ToString());
            }
            catch (Exception e)
            {
                Exception baseException = e.GetBaseException();
                Console.WriteLine("Error: {0}, Message: {1}", e.Message, baseException.Message);
            }
            finally
            {
                Console.WriteLine("End of demo, press any key to exit.");
                Console.ReadKey();
            }
        }
private static async Task ItemOperationsWithValidPartitionKeyValue(Container container)
        {
            string itemid = Guid.NewGuid().ToString();
            string partitionKey = "a";
            DeviceInformationItem itemWithPK = GetDeviceWithPartitionKey(itemid, partitionKey);

            // Insert a new item
            ItemResponse<DeviceInformationItem> createResponse = await container.CreateItemAsync<DeviceInformationItem>(
             partitionKey: new PartitionKey(partitionKey),
             item: itemWithPK);
            Console.WriteLine("Creating Item {0} with Partition Key Status Code {1}", itemid, createResponse.StatusCode);

            // Read the item back
            ItemResponse<DeviceInformationItem> readResponse = await container.ReadItemAsync<DeviceInformationItem>(
                partitionKey: new PartitionKey(partitionKey),
                id: itemid);
            Console.WriteLine("Reading Item {0} with Partition Key Status Code {1}", itemid, readResponse.StatusCode);

            // Replace the content of the item
            itemWithPK.DeviceId = Guid.NewGuid().ToString();
            ItemResponse<DeviceInformationItem> replaceResponse = await container.ReplaceItemAsync<DeviceInformationItem>(
                 partitionKey: new PartitionKey(partitionKey),
                 id: itemWithPK.Id,
                 item: itemWithPK);
            Console.WriteLine("Replacing Item {0} with Partition Key Status Code {1}", itemid, replaceResponse.StatusCode);

            // Delete the item.
            ItemResponse<DeviceInformationItem> deleteResponse = await container.DeleteItemAsync<DeviceInformationItem>(
                partitionKey: new PartitionKey(partitionKey),
                id: itemid);
            Console.WriteLine("Deleting Item {0} with Partition Key Status Code {1}", itemid, deleteResponse.StatusCode);
        }

Upsert Operation

UpsertDocumentAsync - 2.x

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"));
        }

UpsertItemAsync - 3.x

UpsertItemAsync - 3.x

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);
        }

UpsertDocumentAsync - CosmonautClient

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

DeleteDocumentAsync - 2.x

 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);
        }

DeleteDocumentCollectionAsync - 2.x

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);
        }

DeleteItemAsync - 3.x

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);
        }

DeleteDocumentAsync - CosmonautClient

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();
             }

DeleteContainerAsync Sample

public class Program
    {
        //Assign a id for your database & collection 
        private static readonly string DatabaseId = "samples-db";
        private static readonly string ContainerId = "serversidejs-samples";

        // Async main requires c# 7.1 which is set in the csproj with the LangVersion attribute
        // <Main>
        public static async Task Main(string[] args)
        {
            try
            {
                IConfigurationRoot configuration = new ConfigurationBuilder()
                    .AddJsonFile("appSettings.json")
                    .Build();

                string endpoint = configuration["EndPointUrl"];
                if (string.IsNullOrEmpty(endpoint))
                {
                    throw new ArgumentNullException("Please specify a valid endpoint in the appSettings.json");
                }

                string authKey = configuration["AuthorizationKey"];
                if (string.IsNullOrEmpty(authKey) || string.Equals(authKey, "Super secret key"))
                {
                    throw new ArgumentException("Please specify a valid AuthorizationKey in the appSettings.json");
                }

                //Read the Cosmos endpointUrl and authorisationKeys from configuration
                //These values are available from the Azure Management Portal on the Cosmos Account Blade under "Keys"
                //NB > Keep these values in a safe & secure location. Together they provide Administrative access to your Cosmos account
                using (CosmosClient client = new CosmosClient(endpoint, authKey))
                {
                    await Program.RunDemoAsync(client, DatabaseId, ContainerId);
                }
            }
            catch (CosmosException cre)
            {
                Console.WriteLine(cre.ToString());
            }
            catch (Exception e)
            {
                Exception baseException = e.GetBaseException();
                Console.WriteLine("Error: {0}, Message: {1}", e.Message, baseException.Message);
            }
            finally
            {
                Console.WriteLine("End of demo, press any key to exit.");
                Console.ReadKey();
            }
        }
private static async Task RunDemoAsync(
            CosmosClient client,
            string databaseId,
            string containerId)
        {
            Database database = await client.CreateDatabaseIfNotExistsAsync(DatabaseId);

            ContainerProperties containerSettings = new ContainerProperties(containerId, "/LastName");

            // Delete the existing container to prevent create item conflicts
            using (await database.GetContainer(containerId).DeleteContainerStreamAsync())
            { }

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

            //Run a simple script
            await Program.RunSimpleScript(container);

            // Run Bulk Import
            await Program.RunBulkImport(container);

            // Run OrderBy
            await Program.RunOrderBy(container);

            //// Uncomment to Cleanup
            //await database.DeleteAsync();
        }
             

Reading App.config

CreateDocumentAsync - 2.x

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);

}

App.config:

<?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>

Known Limitations

  • Unknown database and collection objects are created when unable to resolve Database and Collection