Rystem.RepositoryFramework.Infrastructure.Azure.Cosmos.Sql
10.0.8
See the version list below for details.
dotnet add package Rystem.RepositoryFramework.Infrastructure.Azure.Cosmos.Sql --version 10.0.8
NuGet\Install-Package Rystem.RepositoryFramework.Infrastructure.Azure.Cosmos.Sql -Version 10.0.8
<PackageReference Include="Rystem.RepositoryFramework.Infrastructure.Azure.Cosmos.Sql" Version="10.0.8" />
<PackageVersion Include="Rystem.RepositoryFramework.Infrastructure.Azure.Cosmos.Sql" Version="10.0.8" />
<PackageReference Include="Rystem.RepositoryFramework.Infrastructure.Azure.Cosmos.Sql" />
paket add Rystem.RepositoryFramework.Infrastructure.Azure.Cosmos.Sql --version 10.0.8
#r "nuget: Rystem.RepositoryFramework.Infrastructure.Azure.Cosmos.Sql, 10.0.8"
#:package Rystem.RepositoryFramework.Infrastructure.Azure.Cosmos.Sql@10.0.8
#addin nuget:?package=Rystem.RepositoryFramework.Infrastructure.Azure.Cosmos.Sql&version=10.0.8
#tool nuget:?package=Rystem.RepositoryFramework.Infrastructure.Azure.Cosmos.Sql&version=10.0.8
Rystem.RepositoryFramework.Infrastructure.Azure.Cosmos.Sql
Rystem.RepositoryFramework.Infrastructure.Azure.Cosmos.Sql adds a Cosmos DB SQL API adapter for Repository Framework.
It is a thin integration: one container per model, one Cosmos item per entity, and a fixed partition key strategy based on /id.
Installation
dotnet add package Rystem.RepositoryFramework.Infrastructure.Azure.Cosmos.Sql
Architecture
At registration time the builder:
- creates the Cosmos database if missing
- creates the container if missing
- uses
/idas the container partition key path
At write time the repository builds an item like this:
id: string form ofTKeyusingKeySettings<TKey>.Instance.AsString(key)- every public property from
T
So the Cosmos item key and the Repository Framework key are tightly coupled.
Registration APIs
Available on all three patterns:
WithCosmosSqlAsync(...)WithCosmosSql(...)
Supported for:
IRepositoryBuilder<T, TKey>ICommandBuilder<T, TKey>IQueryBuilder<T, TKey>
The sync overloads are wrappers over the async implementations.
There is no service-connection registration variant in this package.
Example with a simple key
This mirrors the API tests.
await builder.Services.AddRepositoryAsync<SuperUser, string>(async repositoryBuilder =>
{
await repositoryBuilder.WithCosmosSqlAsync(cosmosBuilder =>
{
cosmosBuilder.Settings.ConnectionString = builder.Configuration["ConnectionStrings:CosmosSql"];
cosmosBuilder.Settings.DatabaseName = "BigDatabase";
cosmosBuilder.WithId(x => x.Email!);
});
});
Example with a custom key type
This follows the integration tests.
await builder.Services.AddRepositoryAsync<AppUser, AppUserKey>(async repositoryBuilder =>
{
await repositoryBuilder.WithCosmosSqlAsync(cosmosBuilder =>
{
cosmosBuilder.Settings.ConnectionString = builder.Configuration["ConnectionStrings:CosmosSql"];
cosmosBuilder.Settings.DatabaseName = "unittestdatabase";
cosmosBuilder.WithId(x => new AppUserKey(x.Id));
}, name: "cosmos");
});
Builder API
ICosmosSqlRepositoryBuilder<T, TKey> exposes:
| Member | Purpose |
|---|---|
Settings |
Cosmos connection and provisioning settings |
WithId(expr) |
Registers a default key manager that reads TKey from a model instance |
WithKeyManager<T>() |
Registers a custom ICosmosSqlKeyManager<T, TKey> |
Configuration and defaults
CosmosSqlConnectionSettings exposes:
| Property | Notes |
|---|---|
ConnectionString |
Used when present. If both this and EndpointUri are set, connection string wins. |
EndpointUri |
Used for managed identity mode. |
ManagedIdentityClientId |
Null means system-assigned identity. |
DatabaseName |
Required in practice. |
ContainerName |
Defaults to typeof(T).Name. |
ClientOptions |
Passed to CosmosClient. |
DatabaseOptions |
Used only during CreateDatabaseIfNotExistsAsync(...). |
ContainerOptions |
Used only during CreateContainerIfNotExistsAsync(...). |
Default lifetime:
Singleton
Managed identity note
Managed identity is used only when:
ConnectionString == null- and
EndpointUri != null
If both are configured, the builder silently uses the connection string path.
Provisioning and lifecycle
Database and container creation happen during registration, not during warm-up.
That means WithCosmosSqlAsync(...) eagerly performs the create-if-not-exists calls.
CosmosSqlRepository<T, TKey>.BootstrapAsync() currently returns true and does nothing.
Key behavior
There are two separate key concerns in this package.
1. How the repository addresses Cosmos items
CRUD methods always use:
KeySettings<TKey>.Instance.AsString(key)
That string becomes both:
- the Cosmos item
id - the partition key value
2. How query results rebuild TKey
WithId(...) and WithKeyManager<T>() are used when the repository has to reconstruct TKey from an entity returned by Cosmos.
Important caveat:
- the custom key manager's
Read(entity)is used for query results - but CRUD methods do not use the key manager's string conversion
So a custom ICosmosSqlKeyManager<T, TKey> cannot change the actual Cosmos id serialization strategy. That is still controlled by KeySettings<TKey>.
Fixed partition key strategy
The container partition key path is always created as:
PartitionKeyPath = "/id"
This package does not expose a builder API to use another partition key path.
Query behavior
QueryAsync(...) partially uses Cosmos LINQ and partially falls back to local processing.
What is pushed to Cosmos:
Where
What is applied locally after materializing results:
OrderByOrderByDescendingThenByThenByDescendingSkipTop
So the flow is:
- run the
Whereportion against Cosmos - materialize matching items into memory
- apply ordering and paging locally
This is important for large datasets, because QueryAsync(...) is not server-side paging over ordered results.
Aggregate behavior
OperationAsync(...) uses Cosmos LINQ aggregates over the queryable for:
CountSumMaxMinAverage
That makes aggregate behavior more efficient than QueryAsync(...) plus client-side aggregation, but it still follows the generic Repository Framework operation model.
CRUD and batch behavior
InsertAsyncusesCreateItemAsync(...)UpdateAsyncusesUpsertItemAsync(...)DeleteAsyncdeletes byidand partition keyExistAsyncruns a parameterized SQL query onidBatchAsync(...)is a sequential loop over operations, not a Cosmos transactional batch
So the package does not currently use Cosmos transactional batch support or rollback semantics.
CQRS examples
await builder.Services.AddCommandAsync<AppUser, AppUserKey>(async commandBuilder =>
{
await commandBuilder.WithCosmosSqlAsync(cosmosBuilder =>
{
cosmosBuilder.Settings.ConnectionString = builder.Configuration["ConnectionStrings:CosmosSql"];
cosmosBuilder.Settings.DatabaseName = "app-database";
cosmosBuilder.WithId(x => new AppUserKey(x.Id));
});
});
await builder.Services.AddQueryAsync<AppUser, AppUserKey>(async queryBuilder =>
{
await queryBuilder.WithCosmosSqlAsync(cosmosBuilder =>
{
cosmosBuilder.Settings.ConnectionString = builder.Configuration["ConnectionStrings:CosmosSql"];
cosmosBuilder.Settings.DatabaseName = "app-database";
cosmosBuilder.WithId(x => new AppUserKey(x.Id));
});
});
When to use this package
Use it when you want:
- a straightforward Cosmos SQL repository adapter
- easy mapping from repository key to Cosmos
id - container provisioning handled by registration
Be careful when you need a custom partitioning strategy or fully server-side ordered paging, because the current implementation does not provide either.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Azure.Identity (>= 1.21.0)
- Microsoft.Azure.Cosmos (>= 3.59.0)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.8)
- Newtonsoft.Json (>= 13.0.4)
- Rystem.RepositoryFramework.Abstractions (>= 10.0.8)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 10.1.0-beta.3 | 66 | 8/26/2026 |
| 10.1.0-beta.2 | 65 | 8/26/2026 |
| 10.0.8 | 60,737 | 5/13/2026 |
| 10.0.7 | 142 | 3/26/2026 |
| 10.0.6 | 433,516 | 3/3/2026 |
| 10.0.5 | 144 | 2/22/2026 |
| 10.0.4 | 145 | 2/9/2026 |
| 10.0.3 | 147,923 | 1/28/2026 |
| 10.0.1 | 209,108 | 11/12/2025 |
| 9.1.3 | 289 | 9/2/2025 |
| 9.1.2 | 764,495 | 5/29/2025 |
| 9.1.1 | 97,838 | 5/2/2025 |
| 9.0.32 | 186,746 | 4/15/2025 |
| 9.0.31 | 5,823 | 4/2/2025 |
| 9.0.30 | 88,880 | 3/26/2025 |
| 9.0.29 | 9,062 | 3/18/2025 |
| 9.0.28 | 305 | 3/17/2025 |
| 9.0.27 | 275 | 3/16/2025 |
| 9.0.26 | 294 | 3/13/2025 |
| 9.0.25 | 52,165 | 3/9/2025 |