Exploring LiteDB

Last year I saw a reference to LiteDB on Awesome .NET. It described itself as "An embedded NoSQL database for .NET". That drew my attention. A short examination of their documents further peaked my interest.

LiteDB describes its target scenarios in the Where to use section of the GitHub repo's readme.

  • Desktop/local small applications
  • Application file format
  • Small web applications
  • One database per account/user data store
  • Few concurrent write operations

LiteDB will almost always be an inappropriate choice for persistence needs outside of these targets but within them it can be a simple to implement and effective solution.

For my exploration I created the litedb branch of the Stupid Todo reference application. In this branch I replaced the static data provider used in the master branch version of StupidTodo.WebApi.TodoController with a LiteDB implementation. Code examples shown here are snippets from that branch.

Using LiteDB

To get started with LiteDB just include the NuGet package. Note that the only dependencies are .NET 4.5 or .NET Standard 2.0 so it's compatible with the vast majority of .NET and .NET Core projects.

Install-Package LiteDB  

Most interactions with LiteDB will begin with an instance of LiteDatabase. Shown is the simplest where LiteDB looks for a file named stupid-todo.db in the execution directory and creates a new one (< 10 kb) if the file is not found.

using (var database = new LiteDatabase("stupid-todo.db"))  
{ ... }

CRUD operations with LiteDB are equally simple. Notice how GetCollection joins a specific .NET Type with a named collection in the database, i.e. the Todo Type joined to the todos collection. The resulting LiteCollection is then used to perform operations.

LiteCollection<Todo> todos = database.GetCollection<Todo>("todos");

// Get all Todo as an array
Todo[] allTodos = todos.FindAll().ToArray();

// Insert or update a Todo
bool upsertResult = todos.Upsert(todo);

// Delete Todo
bool deleteResult = todos.Delete(id);

Illustrated here are LiteCollection instance methods FindAll, Upsert and Delete but there are many others including Find, Insert, Update and Exists each with overloads.

LiteDB also supports a simple indexing mechanism. Call an overload of EnsureIndex after insert/update/upsert and the index will be added if it doesn't exist (Id fields are automatically indexed).

// Ensure a unique index on the Todo's Description field
todos.EnsureIndex(t => t.Description, true);  


Summary

LiteDB shows a focus on simplicity throughout. Its API is limited but sufficient for its target use cases. It's clearly not the right persistence solution for most scenarios but in its target range it works quite well.


References