LiteDB
The Shiny.DocumentDb.LiteDb package provides a LiteDB-backed document store. LiteDB is a pure-managed, file-based NoSQL embedded database — no native dependencies, no install steps, works on every .NET-supported platform out of the box.
When to Use
Section titled “When to Use”- Embedded apps that want zero native dependencies (managed-only, AOT-friendlier deployments)
- Small datasets (a few thousand documents) where client-side predicate evaluation is acceptable
- Windows-only apps where SQLite native loading is awkward
- Quick prototypes / sample apps
For larger datasets or server-side predicate translation, prefer SQLite or a SQL provider.
Installation
Section titled “Installation”dotnet add package Shiny.DocumentDb.LiteDb-
Direct instantiation
using Shiny.DocumentDb.LiteDb;var store = new LiteDbDocumentStore(new LiteDbDocumentStoreOptions{ConnectionString = "Filename=mydata.db"}); -
Dependency injection
LiteDB uses its own options class — register the store directly:
builder.Services.AddSingleton(new LiteDbDocumentStoreOptions{ConnectionString = "Filename=mydata.db"});options.ConfigureDocument<User>(cfg => cfg.ToCollection());options.ConfigureDocument<Order>(cfg => cfg.ToCollection("orders"));builder.Services.AddSingleton<IDocumentStore, LiteDbDocumentStore>();
Options Reference
Section titled “Options Reference”| Property | Type | Default | Description |
|---|---|---|---|
ConnectionString |
string |
(required) | LiteDB connection string. Use Filename=path.db for file-based storage or Filename=:memory: for in-memory |
CollectionName |
string |
"documents" |
Default collection for unmapped types |
TypeNameResolution |
TypeNameResolution |
ShortName |
How type names are stored |
JsonSerializerOptions |
JsonSerializerOptions? |
null |
JSON serialization settings |
UseReflectionFallback |
bool |
true |
Set to false for AOT safety |
Logging |
Action<string>? |
null |
Diagnostic callback |
Collection-Per-Type Mapping
Section titled “Collection-Per-Type Mapping”var options = new LiteDbDocumentStoreOptions{ ConnectionString = "Filename=mydata.db"};options.ConfigureDocument<User>(cfg => cfg.ToCollection()); // auto-derivedoptions.ConfigureDocument<Order>(cfg => cfg.ToCollection("orders")); // explicit nameoptions.ConfigureDocument<Sensor>(cfg => // explicit name + custom Id{ cfg.ToCollection("sensors"); cfg.MapIdProperty(s => s.DeviceKey);});Storage Layout
Section titled “Storage Layout”Documents are stored as BsonDocument records inside LiteDB collections. Each document carries the same envelope fields as the SQL providers (Id, TypeName, Data, CreatedAt, UpdatedAt) — Data is a real BsonDocument sub-object, not a stringified blob.
Queries
Section titled “Queries”LiteDB does not translate LINQ predicates to a query language. The provider:
- Loads every document of the requested type into memory (filtered only by
TypeName/ collection) - Applies the compiled predicate in C#
- Applies ordering, pagination, and projection in C#
// Fine for small datasetsvar users = await store.Query<User>() .Where(u => u.Age > 25) .OrderBy(u => u.Name) .Paginate(0, 50) .ToList();For datasets larger than a few thousand documents, expect linear scans on every query. There is no way to push a predicate down.
Backup
Section titled “Backup”LiteDbDocumentStore.Backup(path) copies the database to a file. Requires a file-based connection string with a Filename parameter (not available on :memory: stores).
var store = new LiteDbDocumentStore(new LiteDbDocumentStoreOptions{ ConnectionString = "Filename=mydata.db"});await store.Backup("/path/to/backup.db");Backup lives on the concrete LiteDbDocumentStore type, not on IDocumentStore.
Optimistic Concurrency
Section titled “Optimistic Concurrency”MapVersionProperty<T> on LiteDbDocumentStoreOptions enables document-level version checks. Version is stored inside the BSON document — no schema changes required.
new LiteDbDocumentStoreOptions{ ConnectionString = "Filename=mydata.db"};opts.ConfigureDocument<Order>(cfg => cfg.MapVersionProperty(o => o.RowVersion));Temporal History
Section titled “Temporal History”LiteDB supports temporal history — MapTemporal<T> records every version to a {collection}_history sidecar collection, read back via the ITemporalDocumentStore capability interface (History/AsOf/Restore/GetDiffBetween/AsOfAll/…). Resolve or cast to ITemporalDocumentStore; the methods are not on the base IDocumentStore.
Limitations
Section titled “Limitations”- All predicates evaluated in C# after a full load — fine for small datasets, painful for large ones.
- No raw SQL —
Query<T>(string)andQueryStream<T>(string)throwNotSupportedException. - No spatial —
WithinRadius/WithinBoundingBox/NearestNeighborsthrowNotSupportedException. - No
CreateIndexAsync— LiteDB indexes are managed natively if needed. - Single-process — opening the same file from two processes fails.
- Pure-managed binary — no native dependencies, no native loader required.
- Optimistic concurrency works the same way as on the SQL providers.
Upsertdeep-merges in C# with recursive null stripping (matches CosmosDB / MongoDB / IndexedDB semantics).


