LottaDB 4.0.0
dotnet add package LottaDB --version 4.0.0
NuGet\Install-Package LottaDB -Version 4.0.0
<PackageReference Include="LottaDB" Version="4.0.0" />
<PackageVersion Include="LottaDB" Version="4.0.0" />
<PackageReference Include="LottaDB" />
paket add LottaDB --version 4.0.0
#r "nuget: LottaDB, 4.0.0"
#:package LottaDB@4.0.0
#addin nuget:?package=LottaDB&version=4.0.0
#tool nuget:?package=LottaDB&version=4.0.0
![]()
LottaDB
LottaDB is a .NET library that makes it easy to store any POCO in Azure Table Storage with full Lucene search, all with the goodness of LINQ. No schema required -- just define a class and go.
- A lotta power, a little work. Store any C# class with zero attributes. All properties are automatically queryable and searchable.
- A lotta bang for a little buck. Table Storage is the cheapest durable storage in Azure. LottaDB adds Lucene so you get rich queries without the rich pricing.
- A lotta LINQ.
GetManyAsync<T>()andSearch<T>(), .Where(), .OrderBy() etc. - A lotta fidelity. Full JSON roundtrip. Lists, dictionaries, nested objects -- everything survives.
- A lotta views.
On<T>triggers build materialized views with plain C#. - A lotta tenants. One catalog per tenant with multiple databases. Natural isolation, simple cleanup.
- A lotta nothing to operate. Table Storage is serverless. Lucene runs in-process.
- A lotta schema safety. Schema changes are detected automatically -- Lucene index is rebuilt on startup.
- A lotta concurrency.
ChangeAsync<T>()provides atomic read-modify-write with optimistic concurrency and automatic retry.
Sweet spot
LottaDB is ideal for per-user or per-tenant workloads -- think user profiles, settings, activity feeds, personal knowledge bases, mailboxes, or per-project data. Thousands of objects per tenant, thousands of tenants per deployment.
Installation
dotnet add package LottaDB
Quick Start -- Just Store a lotta objects
Just define a class. No attributes, no base classes, no interfaces:
public class Actor
{
public string Username { get; set; } = "";
public string DisplayName { get; set; } = "";
public string AvatarUrl { get; set; } = "";
}
Create a catalog, register the type, and start storing:
var catalog = new LottaCatalog("myapp", "<your Azure Storage connection string>");
var db = await catalog.GetDatabaseAsync("default");
// Save -- a unique key (ULID) is auto-generated
var actor = new Actor { Username = "alice", DisplayName = "Alice" };
await db.SaveAsync(actor);
var key = actor.GetKey(); // e.g. "01JKX3Q7..."
// Point read by key
var loaded = await db.GetAsync<Actor>(key);
// Search -- all properties are automatically queryable
var found = db.Search<Actor>()
.Where(a => a.DisplayName == "Alice")
.ToList();
That's it. No key attribute needed -- a ULID is assigned automatically. Every property on your class is automatically:
- Stored as full-fidelity JSON in table storage
- Indexed in Lucene for fast search
- Queryable via LINQ expressions and full-text search
Fine-Tuning with Attributes
When you need more control, attributes let you specify keys, indexing behavior, and exclusions:
public class Note
{
[Key] // explicit key property
public string NoteId { get; set; } = "";
[Queryable(QueryableMode.NotAnalyzed)] // exact match only
public string AuthorId { get; set; } = "";
[Queryable] // full-text search
public string Content { get; set; } = "";
[NotQueryable] // exclude from indexing (e.g., large payloads)
public string RawHtml { get; set; } = "";
public DateTimeOffset Published { get; set; }
public List<string> Tags { get; set; } = new();
}
| Attribute | Effect |
|---|---|
[Key] |
Designates the unique key property. Without it, a ULID is auto-generated. |
[Queryable] |
Controls how a property is indexed. Strings get full-text search by default. |
[NotQueryable] |
Excludes a property from automatic indexing (useful for large strings). |
[DefaultSearch] |
(class-level) Sets the default property for free-text queries. |
Concurrency
ChangeAsync<T>() provides safe read-modify-write with automatic retry on conflict:
await db.ChangeAsync<Actor>("alice", actor =>
{
actor.DisplayName = "Alice Updated";
});
Multiple concurrent writers on the same key are handled correctly -- ETag-based optimistic concurrency ensures no updates are lost.
Storage Providers
LottaDB works with Azure Table Storage out of the box. For local development and testing, install a provider package:
| Package | Install | Usage | Description |
|---|---|---|---|
| LottaDB | dotnet add package LottaDB |
catalog.UseAzure(connectionString) |
The default provider. Uses Azure Table Storage API for durability. |
| LottaDB.Memory | dotnet add package LottaDB.Memory |
catalog.UseMemory() |
In-memory provider for unit testing. No durability, but lightning fast and supports all features. |
| LottaDB.SQLite | dotnet add package LottaDB.SQLite |
catalog.UseSQLite(path) |
Local storage with SQLite. Durable and supports all features, but no serverless scaling. |
// Local development with SQLite
var catalog = new LottaCatalog("myapp", catalog => catalog.UseSQLite(@"C:\data"));
// Unit tests with in-memory storage
var catalog = new LottaCatalog("myapp", catalog => catalog.UseMemory());
Documentation
Full documentation is available in the wiki:
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Azure.Data.Tables (>= 12.11.0)
- Azure.Storage.Blobs (>= 12.28.0)
- Iciclecreek.Lucene.Net.Linq (>= 4.8.5-beta00017)
- Lucene.Net.Store.Azure (>= 4.8.5-beta021)
- MimeMapping (>= 4.0.0)
- Ulid (>= 1.4.1)
-
net8.0
- Azure.Data.Tables (>= 12.11.0)
- Azure.Storage.Blobs (>= 12.28.0)
- Iciclecreek.Lucene.Net.Linq (>= 4.8.5-beta00017)
- Lucene.Net.Store.Azure (>= 4.8.5-beta021)
- MimeMapping (>= 4.0.0)
- System.IO.Pipelines (>= 10.0.8)
- System.Linq.Async (>= 7.0.1)
- Ulid (>= 1.4.1)
NuGet packages (3)
Showing the top 3 NuGet packages that depend on LottaDB:
| Package | Downloads |
|---|---|
|
LottaDB.Tiki
Tiki.Net integration for LottaDB — auto-extract rich metadata from blobs on upload. |
|
|
LottaDB.Memory
In-memory storage provider for LottaDB. Adds UseMemory() extension method for fast unit testing with no disk I/O. |
|
|
LottaDB.SQLite
SQLite storage provider for LottaDB. Adds UseSQLite() extension method for local development with a single portable .db file. |
GitHub repositories
This package is not used by any popular GitHub repositories.