Introducing AI Conversations: Natural Language Interaction for Your Apps! Learn More
DocumentDB Releases
5.0 - TBD
Section titled “5.0 - TBD”Backup removed from IDocumentStore interface — now available only on concrete types: SqliteDocumentStore.Backup(), SqlCipherDocumentStore.Backup(), and LiteDbDocumentStore.Backup()Provider-specific DI extension methods removed (
AddSqliteDocumentStore, AddSqlCipherDocumentStore, AddSqlServerDocumentStore, AddMySqlDocumentStore, AddPostgreSqlDocumentStore, AddLiteDbDocumentStore, AddCosmosDbDocumentStore, AddIndexedDbDocumentStore). Use AddDocumentStore from Shiny.DocumentDb.Extensions.DependencyInjection instead Feature
Named/keyed document store support —
AddDocumentStore("name", opts => ...) registers stores as .NET keyed singletons. Inject with [FromKeyedServices("name")] or resolve dynamically via IDocumentStoreProvider.GetStore("name") Feature
Multi-tenancy support — two isolation strategies via
Shiny.DocumentDb.Extensions.DependencyInjection: shared-table (single database with automatic TenantId column filtering) and tenant-per-database (separate database per tenant via lazy factory) Feature
ITenantResolver interface — implement to provide the current tenant ID. Used by both multi-tenancy strategies to auto-resolve tenant context per request Feature
AddDocumentStore(configure, multiTenant: true) — shared-table multi-tenancy registration. Adds a dedicated TenantId column and index to the schema; all queries are automatically filtered by the current tenant Feature
AddMultiTenantDocumentStore(Func<string, DocumentStoreOptions>) — tenant-per-database registration. Each tenant gets a lazily-created separate database. IDocumentStore is registered as scoped and resolves to the correct tenant automatically Feature
TenantIdAccessor on DocumentStoreOptions — core pipeline hook for shared-table multi-tenancy. When set, all queries include a TenantId filter and all inserts include the tenant value. A dedicated column and index are created automatically Feature
New
Shiny.DocumentDb.IndexedDb package — IndexedDB provider for Blazor WebAssembly with IndexedDbDocumentStore. Zero native dependencies, persists to the browser’s IndexedDB via JS interop Feature
SQLite WASM compatibility —
SqliteDatabaseProvider now skips WAL pragma on OperatingSystem.IsBrowser(), spatial R*Tree is disabled in WASM, and Backup() is marked [UnsupportedOSPlatform("browser")] Feature
New
Shiny.DocumentDb.LiteDb package — LiteDB provider with LiteDbDocumentStore Feature
New
Shiny.DocumentDb.CosmosDb package — Azure Cosmos DB provider with CosmosDbDocumentStore Feature
Spatial/geo query support —
WithinRadius, WithinBoundingBox, and NearestNeighbors methods on IDocumentStore with default NotSupportedException for unsupported providers Feature
GeoPoint readonly record struct — represents a WGS84 coordinate, serializes as GeoJSON {"type":"Point","coordinates":[lng,lat]} Feature
GeoBoundingBox readonly record struct for area-based spatial queries Feature
SpatialResult<T> wrapper — returns documents with computed DistanceMeters from the query center point Feature
MapSpatialProperty<T> on DocumentStoreOptions — register which GeoPoint property to use for spatial indexing per document type Feature
SQLite spatial support via
R*Tree virtual tables — automatic sidecar table creation and CRUD sync for spatial-indexed documents Feature
CosmosDB spatial support via native
ST_DISTANCE and ST_WITHIN GeoJSON queries with automatic spatial index policy Feature
SupportsSpatial property on IDocumentStore — check if the current provider supports spatial queries at runtime Feature
SqliteDocumentStore.ClearAllAsync() — deletes all documents across all tables in the SQLite database, including spatial sidecar tables Feature
Optimistic concurrency via document-level version properties —
MapVersionProperty<T>(x => x.RowVersion) on all provider options classes. Version is set to 1 on insert, checked and incremented on update/upsert. Throws ConcurrencyException on mismatch. Stored inside the JSON blob — zero schema changes required Feature
AOT-safe
MapVersionProperty<T> overload — MapVersionProperty<T>(string propertyName, Func<T, int> getter, Action<T, int> setter) for trimming-safe deployments Feature
ConcurrencyException — new exception type with TypeName, DocumentId, ExpectedVersion, and ActualVersion properties for diagnosing version conflicts4.0 - April 30, 2026
Section titled “4.0 - April 30, 2026” Feature
New
Shiny.DocumentDb.Extensions.AI package — exposes IDocumentStore operations as Microsoft.Extensions.AI tool functions for LLM agents Feature
AddDocumentStoreAITools DI extension — opt-in registration of document types with per-type capability flags (ReadOnly, All, or individual Get/Query/Count/Aggregate/Insert/Update/Delete) Feature
Seven AI tool functions generated per type (when using
All): get_by_id, query, count, aggregate, insert, update, delete Feature
Structured JSON filter expressions with
and/or/not combinators and leaf comparisons (eq, ne, gt, gte, lt, lte, contains, startsWith, in) — translated to LINQ expressions at runtime Feature
Per-type builder API:
Description(), Property() description overrides, AllowProperties() / IgnoreProperties() for field visibility control, MaxPageSize() to cap query results Feature
AOT-safe — all tool schemas and serialization use
JsonTypeInfo<T> from source-generated JSON contexts Feature
Aggregate tool supports
count, sum, min, max, avg functions with optional structured filters Feature
DocumentStoreAITools wrapper class — resolve from DI and pass .Tools to IChatClient / ChatOptions.Tools Feature
GitHub Copilot sample app demonstrating interactive document management via LLM chat
3.2 - March 26, 2026
Section titled “3.2 - March 26, 2026” Feature
New
Shiny.DocumentDb.Sqlite.SqlCipher package — encrypted SQLite via SQLCipher with a separate native bundle, no changes to the existing Shiny.DocumentDb.Sqlite package Feature
SqlCipherDatabaseProvider(filePath, password) — explicit file path and password parameters so users know exactly what is required Feature
SqlCipherDocumentStore convenience wrapper and AddSqlCipherDocumentStore DI extension for quick setup Feature
RekeyAsync extension method on IDocumentStore — change the encryption key of an existing SQLCipher database via PRAGMA rekey with SQL injection protection Feature
Backup support for SQLCipher — automatically propagates the encryption password to the backup database
Feature
DocumentStore.DatabaseProvider public property — exposes the underlying IDatabaseProvider for extension methods3.1 - March 24, 2026
Section titled “3.1 - March 24, 2026”Removed
SystemTextJsonPatch dependency — replaced with built-in AOT-compatible JsonPatchDocument<T> and JsonPatchOperation types that use JSON DOM manipulation instead of reflectionJsonPatchDocument<T>.ApplyTo() now returns a new T instead of mutating the target in place — var patched = patch.ApplyTo(original) Feature
New
JsonPatchOperation immutable type with static factory methods: Add, Replace, Remove, Copy, Move, Test Feature
New
JsonPatchDocument<T> with AOT-safe overload accepting JsonTypeInfo<T> — patch.ApplyTo(target, MyJsonContext.Default.MyType) Feature
BatchInsert<T> now uses multi-row INSERT statements chunked into batches of 500 rows, significantly reducing database round-trips — especially impactful for PostgreSQL3.0 - March 23, 2026
Section titled “3.0 - March 23, 2026”Package renamed from
Shiny.SqliteDocumentDb to Shiny.DocumentDb with separate provider packages: Shiny.DocumentDb.Sqlite, Shiny.DocumentDb.SqlServer, Shiny.DocumentDb.MySql, Shiny.DocumentDb.PostgreSqlConnectionString removed from DocumentStoreOptions — replaced by required IDatabaseProvider DatabaseProvider. The connection string is now passed to each provider’s constructorDI extensions bundled into each provider package — no separate
Shiny.SqliteDocumentDb.Extensions.DependencyInjection packageSqliteDocumentStore moved to Shiny.DocumentDb.Sqlite namespace. Base class is now DocumentStore in Shiny.DocumentDb Feature
SQL Server provider via
Shiny.DocumentDb.SqlServer with AddSqlServerDocumentStore DI extension Feature
MySQL provider via
Shiny.DocumentDb.MySql with AddMySqlDocumentStore DI extension Feature
PostgreSQL provider via
Shiny.DocumentDb.PostgreSql with AddPostgreSqlDocumentStore DI extension Feature
Provider-agnostic
IDatabaseProvider interface — swap database backends without changing application code2.0 - March 22, 2026
Section titled “2.0 - March 22, 2026”DI extensions moved to separate
Shiny.SqliteDocumentDb.Extensions.DependencyInjection package — the core library no longer depends on Microsoft.Extensions.DependencyInjection.Abstractions Feature
Convenience constructor —
new SqliteDocumentStore("Data Source=mydata.db") for quick setup without options Feature
Configurable default table name via
DocumentStoreOptions.TableName (defaults to "documents") Feature
Table-per-type mapping —
MapTypeToTable<T>() gives a document type its own dedicated SQLite table with lazy creation on first use Feature
Auto-derived or explicit table names —
MapTypeToTable<T>() derives from the type name, MapTypeToTable<T>(string) uses an explicit name Feature
Duplicate table name protection — mapping two types to the same custom table throws
InvalidOperationException Feature
Custom Id property mapping —
MapTypeToTable<T>("table", x => x.MyProperty) uses an alternate property as the document Id instead of the default Id Feature
Fluent options API — all
MapTypeToTable overloads return DocumentStoreOptions for chaining Feature
Document diffing via
GetDiff<T>(id, modified) — compares a modified object against the stored document and returns an RFC 6902 JsonPatchDocument<T> with deep nested-object diffing powered by SystemTextJsonPatch Feature
All new features are fully AOT-safe — type names and Id property names are resolved at registration time, not at runtime
Feature
Batch insert via
BatchInsert<T>(IEnumerable<T>) — inserts a collection in a single transaction with prepared command reuse, auto-generates IDs, and rolls back atomically on failure1.0 - March 6, 2026
Section titled “1.0 - March 6, 2026” Feature
Schema-free JSON document storage on top of SQLite
Feature
Mandatory typed
Id property on document types (Guid, int, long, or string) — stored in both the SQLite column and the JSON blob so query results always include it Feature
Auto-generation of Ids on Insert:
Guid → Guid.NewGuid(), int/long → MAX(CAST(Id AS INTEGER)) + 1 per TypeName. String Ids must be set explicitly — Insert throws for default string Ids Feature
LINQ expression queries translated to json_extract SQL with support for equality, comparisons, logical operators, null checks, string methods, nested properties, and collection queries
Feature
Fluent query builder (IDocumentQuery) — chain .Where(), .OrderBy(), .OrderByDescending(), .GroupBy(), .Paginate(), .Select() and terminate with .ToList(), .ToAsyncEnumerable(), .Count(), .Any(), .ExecuteDelete(), .ExecuteUpdate(), .Max(), .Min(), .Sum(), .Average()
Feature
Pagination via .Paginate(offset, take) — translates to SQL LIMIT/OFFSET
Feature
Expression-based ordering — .OrderBy(u => u.Age) and .OrderByDescending(u => u.Name) on the fluent query builder
Feature
SQL-level projections via .Select() using json_object for extracting specific fields without full deserialization
Feature
IAsyncEnumerable streaming via .ToAsyncEnumerable() — yield results one-at-a-time without buffering
Feature
Expression-based JSON indexes for up to 30x faster queries on indexed properties
Feature
Full AOT and trimming support — all JsonTypeInfo parameters are optional and auto-resolve from configured JsonSerializerContext
Feature
Scalar aggregates: .Max(), .Min(), .Sum(), .Average() as terminal methods on the query builder
Feature
Aggregate projections with automatic GROUP BY via Sql.Count(), Sql.Max(), Sql.Min(), Sql.Sum(), Sql.Avg() marker methods
Feature
Collection-level aggregates in projections: Sum, Min, Max, Average on child collections (e.g. o.Lines.Sum(l => l.Quantity))
Feature
Explicit Insert / Update / Upsert API — Insert throws on duplicate Ids, Update throws if not found, Upsert deep-merges via json_patch
Feature
SetProperty — update a single scalar JSON field via json_set without deserializing the document. Supports nested paths
Feature
RemoveProperty — strip a field from the stored JSON via json_remove. Works on any property type
Feature
Typed Id lookups — Get, Remove, SetProperty, and RemoveProperty accept the Id as
object (Guid, int, long, or string). Unsupported types throw ArgumentException Feature
Bulk delete via query builder — .Where(predicate).ExecuteDelete() returns count of deleted documents
Feature
Bulk update via query builder — .Where(predicate).ExecuteUpdate(property, value) updates a property on matching documents via json_set() and returns count updated
Feature
Transactions with automatic commit/rollback via RunInTransaction
Feature
Hot backup via store.Backup(path) — copies the database to a file using the SQLite Online Backup API while the store remains usable
Feature
Dependency injection registration via AddSqliteDocumentStore
Feature
Configurable type name resolution (ShortName or FullName)
Feature
UseReflectionFallback option for strict AOT enforcement
Feature
SQL logging callback via DocumentStoreOptions.Logging
Feature
Raw SQL query and streaming support via store.Query(whereClause) and store.QueryStream(whereClause)