Skip to content
mbdavid edited this page Jul 25, 2016 · 13 revisions

LiteDB is a document database, so there is no JOIN between collections. You can use embedded documents (sub-documents) or create a reference between collections. To create this reference you must use DbRef method from fluent api mapper (there is no attribute for that).

Mapping a reference on database initialization

public class Customer
{
    public int CustomerId { get; set; }
    public string Name { get; set; }
}

public class Order
{
    public int OrderId { get; set; }
    public Customer Customer { get; set; }
}

If you didn't do any mapping, when you save an Order, Customer are saved as an embedded document (with no link to any other collection). If you change customer name in Customer colleciton this change will not affect Order.

Order => { _id: 123, Customer: { CustomerId: 99, Name: "John Doe" } }

If you want store only customer reference in Order, use:

BsonMapper.Global.Entity<Order>()
    .DbRef(x => x.Customer, "customers");

Now, when you store Order you are storing only link reference.

Order => { _id: 123, Customer: { $id: 4, $ref: "customers"} }

Quering results

When you query a document with a cross collection reference, you can auto load references using Include method before query.

var orders = db.GetCollection<Order>("orders");

var order1 = db
    .Include(x => x.Customer)
    .FindById(1);

DbRef also support List<T> or Array, like:

public class Product
{
    public int ProductId { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
}

public class Order
{
    public int OrderId { get; set; }
    public DateTime OrderDate { get; set; }
    public List<Product> Products { get; set; }
}

BsonMapper.Global.Entity<Order>()
    .DbRef(x => x.Products);

LiteDB will respect if you Products field are null or empty list when restore from datafile. If you do not use Include in query, classes are loaded with only ID setted (all other properties will stay with default/null value).