Skip to content
Document DB v12 - Improved Interceptors with Soft Delete Integration, AI protections, & Admin UI with Aspire Integration!How!?

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.

NuGet package Shiny.DocumentDb.LiteDb
  • 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.

Terminal window
dotnet add package Shiny.DocumentDb.LiteDb
  1. Direct instantiation

    using Shiny.DocumentDb.LiteDb;
    var store = new LiteDbDocumentStore(new LiteDbDocumentStoreOptions
    {
    ConnectionString = "Filename=mydata.db"
    });
  2. Dependency injection

    LiteDB uses its own options class — register the store directly:

    builder.Services.AddSingleton(new LiteDbDocumentStoreOptions
    {
    ConnectionString = "Filename=mydata.db"
    }
    .MapTypeToCollection<User>()
    .MapTypeToCollection<Order>("orders"));
    builder.Services.AddSingleton<IDocumentStore, LiteDbDocumentStore>();
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
new LiteDbDocumentStoreOptions
{
ConnectionString = "Filename=mydata.db"
}
.MapTypeToCollection<User>() // auto-derived
.MapTypeToCollection<Order>("orders") // explicit name
.MapTypeToCollection<Sensor>("sensors", s => s.DeviceKey) // explicit name + custom Id

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.

LiteDB does not translate LINQ predicates to a query language. The provider:

  1. Loads every document of the requested type into memory (filtered only by TypeName / collection)
  2. Applies the compiled predicate in C#
  3. Applies ordering, pagination, and projection in C#
// Fine for small datasets
var 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.

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.

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"
}.MapVersionProperty<Order>(o => o.RowVersion);

LiteDB supports temporal historyMapTemporal<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.

  • All predicates evaluated in C# after a full load — fine for small datasets, painful for large ones.
  • No raw SQLQuery<T>(string) and QueryStream<T>(string) throw NotSupportedException.
  • No spatialWithinRadius / WithinBoundingBox / NearestNeighbors throw NotSupportedException.
  • 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.
  • Upsert deep-merges in C# with recursive null stripping (matches CosmosDB / MongoDB / IndexedDB semantics).