Rystem.RepositoryFramework.Infrastructure.Azure.Cosmos.Sql 10.0.8

There is a newer prerelease version of this package available.
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
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Rystem.RepositoryFramework.Infrastructure.Azure.Cosmos.Sql" Version="10.0.8" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Rystem.RepositoryFramework.Infrastructure.Azure.Cosmos.Sql" Version="10.0.8" />
                    
Directory.Packages.props
<PackageReference Include="Rystem.RepositoryFramework.Infrastructure.Azure.Cosmos.Sql" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Rystem.RepositoryFramework.Infrastructure.Azure.Cosmos.Sql --version 10.0.8
                    
#r "nuget: Rystem.RepositoryFramework.Infrastructure.Azure.Cosmos.Sql, 10.0.8"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Rystem.RepositoryFramework.Infrastructure.Azure.Cosmos.Sql@10.0.8
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Rystem.RepositoryFramework.Infrastructure.Azure.Cosmos.Sql&version=10.0.8
                    
Install as a Cake Addin
#tool nuget:?package=Rystem.RepositoryFramework.Infrastructure.Azure.Cosmos.Sql&version=10.0.8
                    
Install as a Cake Tool

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:

  1. creates the Cosmos database if missing
  2. creates the container if missing
  3. uses /id as the container partition key path

At write time the repository builds an item like this:

  • id: string form of TKey using KeySettings<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:

  • OrderBy
  • OrderByDescending
  • ThenBy
  • ThenByDescending
  • Skip
  • Top

So the flow is:

  1. run the Where portion against Cosmos
  2. materialize matching items into memory
  3. 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:

  • Count
  • Sum
  • Max
  • Min
  • Average

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

  • InsertAsync uses CreateItemAsync(...)
  • UpdateAsync uses UpsertItemAsync(...)
  • DeleteAsync deletes by id and partition key
  • ExistAsync runs a parameterized SQL query on id
  • BatchAsync(...) 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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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
Loading failed