DocumentDB Releases
3.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)