Skip to content
Introducing AI Conversations: Natural Language Interaction for Your Apps! Learn More

DocumentDB Releases

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 conflicts
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
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 methods
Removed SystemTextJsonPatch dependency — replaced with built-in AOT-compatible JsonPatchDocument<T> and JsonPatchOperation types that use JSON DOM manipulation instead of reflection
JsonPatchDocument<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 PostgreSQL
Package renamed from Shiny.SqliteDocumentDb to Shiny.DocumentDb with separate provider packages: Shiny.DocumentDb.Sqlite, Shiny.DocumentDb.SqlServer, Shiny.DocumentDb.MySql, Shiny.DocumentDb.PostgreSql
ConnectionString removed from DocumentStoreOptions — replaced by required IDatabaseProvider DatabaseProvider. The connection string is now passed to each provider’s constructor
DI extensions bundled into each provider package — no separate Shiny.SqliteDocumentDb.Extensions.DependencyInjection package
SqliteDocumentStore 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 code
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 failure
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: GuidGuid.NewGuid(), int/longMAX(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)