Class CosmosHelper
Azure Cosmos DB data access helper providing async query execution and result mapping. Handles container management, command execution, and result transformation for Cosmos SQL API.
Implements
Inherited Members
Namespace: DataWeb.Data.AzureCosmosDB
Assembly: DataWeb.Data.AzureCosmosDB.dll
Syntax
public class CosmosHelper : ICosmosHelper
Remarks
Implements ICosmosHelper interface with methods for:
- GetListAsync: Execute queries and buffer results into a read-only list with pagination support
- GetValueAsync: Execute scalar queries returning single values
- UpsertItemAsync: Insert or update strongly-typed items
- UpsertDictionaryAsync: Insert or update dictionary-based documents
- SetValueAsync: Patch single document property
- IncrementValueAsync: Atomic increment operation on numeric field
- AddArrayValueAsync: Add element to array field
- DeleteItemAsync: Delete document by ID
All methods support:
- Parameterized queries to prevent injection attacks
- Optional custom Cosmos clients for multi-tenant scenarios
- Cancellation tokens for async operation control
- Detailed logging of query execution
- Container reference caching to optimize performance
Constructors
CosmosHelper(CosmosClient, ILogger<CosmosHelper>)
Azure Cosmos DB data access helper providing async query execution and result mapping. Handles container management, command execution, and result transformation for Cosmos SQL API.
Declaration
public CosmosHelper(CosmosClient defaultClient, ILogger<CosmosHelper> logger)
Parameters
| Type | Name | Description |
|---|---|---|
| CosmosClient | defaultClient | |
| ILogger<CosmosHelper> | logger |
Remarks
Implements ICosmosHelper interface with methods for:
- GetListAsync: Execute queries and buffer results into a read-only list with pagination support
- GetValueAsync: Execute scalar queries returning single values
- UpsertItemAsync: Insert or update strongly-typed items
- UpsertDictionaryAsync: Insert or update dictionary-based documents
- SetValueAsync: Patch single document property
- IncrementValueAsync: Atomic increment operation on numeric field
- AddArrayValueAsync: Add element to array field
- DeleteItemAsync: Delete document by ID
All methods support:
- Parameterized queries to prevent injection attacks
- Optional custom Cosmos clients for multi-tenant scenarios
- Cancellation tokens for async operation control
- Detailed logging of query execution
- Container reference caching to optimize performance
Methods
AddArrayValueAsync(string, string, object, string, string, string, CosmosClient, CancellationToken)
Adds an element to an array property in a document.
Declaration
public Task AddArrayValueAsync(string id, string arrayFieldPath, object value, string storageDatabase, string storageContainer, string partitionKey, CosmosClient client = null, CancellationToken cancellationToken = default)
Parameters
| Type | Name | Description |
|---|---|---|
| string | id | Document ID to update. |
| string | arrayFieldPath | JSON path to the array property (e.g., '/tags', '/items/comments'). |
| object | value | Element to add to the array. |
| string | storageDatabase | Cosmos database name. |
| string | storageContainer | Cosmos container name. |
| string | partitionKey | Partition key value for the document. |
| CosmosClient | client | Optional custom Cosmos client. Uses default if null. |
| CancellationToken | cancellationToken | Token to cancel the async operation. |
Returns
| Type | Description |
|---|---|
| Task |
Remarks
Uses Cosmos DB patch API Add operation for array mutations. Efficient for appending to arrays without retrieving entire document. If array doesn't exist, it will be created.
Examples
await cosmosHelper.AddArrayValueAsync("123", "/tags", "new-tag", "database", "container", "123");
Exceptions
| Type | Condition |
|---|---|
| ArgumentException | Thrown if any required parameter is null/empty. |
DeleteItemAsync<T>(string, string, string, string, CosmosClient, CancellationToken)
Deletes a document from Cosmos DB by ID.
Declaration
public Task DeleteItemAsync<T>(string id, string storageDatabase, string storageContainer, string partitionKey, CosmosClient client = null, CancellationToken cancellationToken = default)
Parameters
| Type | Name | Description |
|---|---|---|
| string | id | Document ID to delete. |
| string | storageDatabase | Cosmos database name. |
| string | storageContainer | Cosmos container name. |
| string | partitionKey | Partition key value for the document. |
| CosmosClient | client | Optional custom Cosmos client. Uses default if null. |
| CancellationToken | cancellationToken | Token to cancel the async operation. |
Returns
| Type | Description |
|---|---|
| Task |
Type Parameters
| Name | Description |
|---|---|
| T | Type associated with the document (for logging/type info). |
Remarks
Requires both ID and partition key for efficient deletion. Does not throw if document doesn't exist (idempotent operation). Container references are cached for performance.
Examples
await cosmosHelper.DeleteItemAsync<Product>("123", "database", "container", "123");
Exceptions
| Type | Condition |
|---|---|
| ArgumentException | Thrown if any required parameter is null/empty. |
DeleteItemsAsync<T>(IEnumerable<(string id, string partitionKey)>, string, string, CosmosClient, CancellationToken)
Deletes multiple documents from Cosmos DB in parallel.
Declaration
public Task DeleteItemsAsync<T>(IEnumerable<(string id, string partitionKey)> items, string storageDatabase, string storageContainer, CosmosClient client = null, CancellationToken cancellationToken = default)
Parameters
| Type | Name | Description |
|---|---|---|
| IEnumerable<(string id, string partitionKey)> | items | |
| string | storageDatabase | |
| string | storageContainer | |
| CosmosClient | client | |
| CancellationToken | cancellationToken |
Returns
| Type | Description |
|---|---|
| Task |
Type Parameters
| Name | Description |
|---|---|
| T |
GetListAsync<T>(Query, string, string, CosmosClient, CancellationToken)
Executes a query and returns a collection of mapped results. Overload accepting a pre-compiled Query object.
Declaration
public Task<IReadOnlyList<T>> GetListAsync<T>(Query query, string storageDatabase, string storageContainer, CosmosClient client = null, CancellationToken cancellationToken = default)
Parameters
| Type | Name | Description |
|---|---|---|
| Query | query | Pre-compiled Query object containing SQL-API query and parameters. |
| string | storageDatabase | Cosmos database name. |
| string | storageContainer | Cosmos container name. |
| CosmosClient | client | Optional custom Cosmos client. Uses default if null. |
| CancellationToken | cancellationToken | Token to cancel the async operation. |
Returns
| Type | Description |
|---|---|
| Task<IReadOnlyList<T>> | Fully materialized read-only list of mapped results, or empty if no documents returned. |
Type Parameters
| Name | Description |
|---|---|
| T | Type to map each document to. |
Examples
var items = await cosmosHelper.GetListAsync(query, "database", "container");
GetListAsync<T>(string, string, string, Dictionary<string, object>, int, long?, CosmosClient, CancellationToken)
Executes a query and returns a collection of mapped results with optional pagination.
Declaration
public Task<IReadOnlyList<T>> GetListAsync<T>(string query, string storageDatabase, string storageContainer, Dictionary<string, object> parameters = null, int count = 0, long? pageIndex = null, CosmosClient client = null, CancellationToken cancellationToken = default)
Parameters
| Type | Name | Description |
|---|---|---|
| string | query | SQL-API query string. |
| string | storageDatabase | Cosmos database name. |
| string | storageContainer | Cosmos container name. |
| Dictionary<string, object> | parameters | Optional dictionary of query parameters for parameterized queries. |
| int | count | Maximum documents to return. 0 = all documents. Sets MaxItemCount optimization. |
| long? | pageIndex | Optional page number for pagination (0-based). If null, uses count-based retrieval. |
| CosmosClient | client | Optional custom Cosmos client. Uses default if null. |
| CancellationToken | cancellationToken | Token to cancel the async operation. |
Returns
| Type | Description |
|---|---|
| Task<IReadOnlyList<T>> | Fully materialized read-only list of mapped results. Pre-allocated based on expected count. |
Type Parameters
| Name | Description |
|---|---|
| T | Type to map each document to. |
Remarks
Supports two pagination modes:
- Count-based: pageIndex=null, count=N retrieves first N documents
- Page-based: pageIndex=0, count=pageSize retrieves specific page with early exit optimization
List is pre-allocated: capacity = count (if count > 0) or estimated from FeedIterator. Container references are cached to avoid repeated SDK lookups.
Exceptions
| Type | Condition |
|---|---|
| ArgumentException | Thrown if query, database, or container is null/empty. |
GetValueAsync<T>(Query, string, string, CosmosClient, CancellationToken)
Executes a scalar query and returns a single mapped value. Overload accepting a pre-compiled Query object.
Declaration
public Task<T> GetValueAsync<T>(Query query, string storageDatabase, string storageContainer, CosmosClient client = null, CancellationToken cancellationToken = default)
Parameters
| Type | Name | Description |
|---|---|---|
| Query | query | Pre-compiled Query object containing SQL-API query and parameters. |
| string | storageDatabase | Cosmos database name. |
| string | storageContainer | Cosmos container name. |
| CosmosClient | client | Optional custom Cosmos client. Uses default if null. |
| CancellationToken | cancellationToken | Token to cancel the async operation. |
Returns
| Type | Description |
|---|---|
| Task<T> | First document from result set cast to type T, or default(T) if empty. |
Type Parameters
| Name | Description |
|---|---|
| T | Type to return (typically for COUNT, SUM, custom scalar selections). |
Remarks
MaxItemCount is optimized to 1 for better performance.
GetValueAsync<T>(string, string, string, Dictionary<string, object>, CosmosClient, CancellationToken)
Executes a scalar query and returns a single mapped value.
Declaration
public Task<T> GetValueAsync<T>(string query, string storageDatabase, string storageContainer, Dictionary<string, object> parameters = null, CosmosClient client = null, CancellationToken cancellationToken = default)
Parameters
| Type | Name | Description |
|---|---|---|
| string | query | SQL-API query string. |
| string | storageDatabase | Cosmos database name. |
| string | storageContainer | Cosmos container name. |
| Dictionary<string, object> | parameters | Optional dictionary of query parameters for parameterized queries. |
| CosmosClient | client | Optional custom Cosmos client. Uses default if null. |
| CancellationToken | cancellationToken | Token to cancel the async operation. |
Returns
| Type | Description |
|---|---|
| Task<T> | First document from result set, or default(T) if no documents returned. |
Type Parameters
| Name | Description |
|---|---|
| T | Type to return (typically for COUNT, SUM, custom scalar selections). |
Remarks
Optimized with MaxItemCount=1 for single-value retrieval. Container references are cached to avoid repeated SDK lookups.
Examples
var count = await cosmosHelper.GetValueAsync<long>("SELECT VALUE COUNT(1) FROM c", ...);
Exceptions
| Type | Condition |
|---|---|
| ArgumentException | Thrown if query, database, or container is null/empty. |
IncrementValueAsync(string, string, long, string, string, string, CosmosClient, CancellationToken)
Atomically increments a numeric field in a document.
Declaration
public Task<long> IncrementValueAsync(string id, string fieldPath, long incrementValue, string storageDatabase, string storageContainer, string partitionKey, CosmosClient client = null, CancellationToken cancellationToken = default)
Parameters
| Type | Name | Description |
|---|---|---|
| string | id | Document ID to update. |
| string | fieldPath | JSON path to the numeric property (e.g., '/count', '/stats/views'). |
| long | incrementValue | Value to add (can be positive or negative). |
| string | storageDatabase | Cosmos database name. |
| string | storageContainer | Cosmos container name. |
| string | partitionKey | Partition key value for the document. |
| CosmosClient | client | Optional custom Cosmos client. Uses default if null. |
| CancellationToken | cancellationToken | Token to cancel the async operation. |
Returns
| Type | Description |
|---|---|
| Task<long> | The new value after increment operation. |
Remarks
Atomic operation prevents race conditions in concurrent increment scenarios. Uses Cosmos DB patch API with Increment operation. More efficient and safer than read-modify-write pattern.
Examples
var newCount = await cosmosHelper.IncrementValueAsync("123", "/viewCount", 1, ...);
Exceptions
| Type | Condition |
|---|---|
| ArgumentException | Thrown if any required parameter is null/empty. |
SetValueAsync(string, string, object, string, string, string, CosmosClient, CancellationToken)
Updates a single property of an existing document using patch operation.
Declaration
public Task SetValueAsync(string id, string fieldPath, object value, string storageDatabase, string storageContainer, string partitionKey, CosmosClient client = null, CancellationToken cancellationToken = default)
Parameters
| Type | Name | Description |
|---|---|---|
| string | id | Document ID to update. |
| string | fieldPath | JSON path to the property (e.g., '/status', '/metadata/updated'). |
| object | value | New value for the property. |
| string | storageDatabase | Cosmos database name. |
| string | storageContainer | Cosmos container name. |
| string | partitionKey | Partition key value for the document. |
| CosmosClient | client | Optional custom Cosmos client. Uses default if null. |
| CancellationToken | cancellationToken | Token to cancel the async operation. |
Returns
| Type | Description |
|---|---|
| Task |
Remarks
Uses Cosmos DB patch API for efficient partial updates. More efficient than full document replacement for single-property updates. Container references are cached for performance.
Examples
await cosmosHelper.SetValueAsync("123", "/status", "active", "database", "container", "123");
Exceptions
| Type | Condition |
|---|---|
| ArgumentException | Thrown if any required parameter is null/empty. |
UpsertDictionaryAsync(Dictionary<string, object>, string, string, string, CosmosClient, CancellationToken)
Inserts or updates a dictionary-based document in Cosmos DB.
Declaration
public Task UpsertDictionaryAsync(Dictionary<string, object> data, string storageDatabase, string storageContainer, string partitionKey, CosmosClient client = null, CancellationToken cancellationToken = default)
Parameters
| Type | Name | Description |
|---|---|---|
| Dictionary<string, object> | data | Dictionary containing document properties. Must contain 'Id' or 'id' key. |
| string | storageDatabase | Cosmos database name. |
| string | storageContainer | Cosmos container name. |
| string | partitionKey | Partition key value for the document. |
| CosmosClient | client | Optional custom Cosmos client. Uses default if null. |
| CancellationToken | cancellationToken | Token to cancel the async operation. |
Returns
| Type | Description |
|---|---|
| Task |
Remarks
Dictionary keys are case-sensitive. Checks for both 'Id' and 'id' variants. Suitable when document schema is dynamic or not strongly-typed. Container references are cached for performance.
Examples
var doc = new Dictionary<string, object> { { "id", "123" }, { "name", "Widget" } }; await cosmosHelper.UpsertDictionaryAsync(doc, "database", "container", "123");
Exceptions
| Type | Condition |
|---|---|
| ArgumentException | Thrown if data is null, database/container/partitionKey is empty, or Id key missing. |
| Exception | Thrown if 'Id' or 'id' key is missing from data dictionary. |
UpsertItemAsync<T>(T, string, string, string, CosmosClient, CancellationToken)
Inserts or updates a strongly-typed item in Cosmos DB.
Declaration
public Task UpsertItemAsync<T>(T item, string storageDatabase, string storageContainer, string partitionKey, CosmosClient client = null, CancellationToken cancellationToken = default)
Parameters
| Type | Name | Description |
|---|---|---|
| T | item | Item to insert or update. Cannot be null. |
| string | storageDatabase | Cosmos database name. |
| string | storageContainer | Cosmos container name. |
| string | partitionKey | Partition key value for the item. |
| CosmosClient | client | Optional custom Cosmos client. Uses default if null. |
| CancellationToken | cancellationToken | Token to cancel the async operation. |
Returns
| Type | Description |
|---|---|
| Task |
Type Parameters
| Name | Description |
|---|---|
| T | Type of item to upsert. |
Remarks
Performs insert if document doesn't exist, or updates if it does. Partition key must be provided and match the partition key definition of the container. Container references are cached for performance.
Examples
var item = new Product { Id = "123", Name = "Widget" }; await cosmosHelper.UpsertItemAsync(item, "database", "container", "123");
Exceptions
| Type | Condition |
|---|---|
| ArgumentException | Thrown if item, database, container, or partitionKey is null/empty. |