Litedb: Insert complex objects

Created on 24 Nov 2017  路  9Comments  路  Source: mbdavid/LiteDB

Hi,
I want to insters complex object to database. Can you verify what I'm doing wronmg?

public class Phone
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public string Number { get; set; }
        }
public class Customer
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public List<Phone> Phones { get; set; }
            public bool IsActive { get; set; }
        }

        static void Main(string[] args)
        {
            using (var db = new LiteDatabase(@"C:\MyData.db"))
            {

                var phones = db.GetCollection<Phone>("phones");
                var customers = db.GetCollection<Customer>("customers");

                BsonMapper.Global.Entity<Customer>()
                    .Id(e => e.Id)
                    .DbRef(e => e.Phones, "phones");

                var customer = new Customer
                {
                    Name = "Dawid",
                    Phones = new List<Phone> { new Phone { Name = " damien", Number = "111222" }, new Phone { Name = " dawid", Number = "555666" } },
                    IsActive = true
                };

                customers.Insert(customer);

                // this list have 1 object, but in this object Phones has Id = 0 and another properties are null
                var allCustomers = customers.Include(c => c.Phones).FindAll().ToList();

                // this list is empty
                var allPhones = phones.FindAll().ToList();
            }
        }
suggestion

Most helpful comment

If there are any concepts or ideas you have that you want feedback on (maybe if you forgot something or just want to get an outside opinion for proofchecking) let us know :)

Maybe we can also help implementing it if you want...

All 9 comments

If Phone are collection reference, you must insert first your phone instance in your phone collection before use in customer. Like this:

```C#
static void Main(string[] args)
{
using (var db = new LiteDatabase(@"C:\MyData.db"))
{

    var phones = db.GetCollection<Phone>("phones");
    var customers = db.GetCollection<Customer>("customers");

    BsonMapper.Global.Entity<Customer>()
        .Id(e => e.Id)
        .DbRef(e => e.Phones, "phones");

    var phone1 = new Phone { Name = " damien", Number = "111222" };
    var phone2 = new Phone { Name = " dawid", Number = "555666" };

    phones.Insert(phone1);
    phones.Insert(phone2);

    var customer = new Customer
    {
        Name = "Dawid",
        Phones = new List<Phone> { phone1, phone2 },
        IsActive = true
    };

    customers.Insert(customer);

    // this list have 1 object, but in this object Phones has Id = 0 and another properties are null
    var allCustomers = customers.Include(c => c.Phones).FindAll().ToList();

    // this list is empty
    var allPhones = phones.FindAll().ToList();
}

}
```

Ok, I understand. But it should inform me somehow that I put known/referenced type without reference/id or insert it automatically :)

Why does it not insert reference objects automatically?
It seems like that should be a standard feature...

Also, an option to automatically include references.

BsonMapper.Global.Entity()
.Id(e => e.Id)
.DbRef(e => e.Phones, "phones", alwaysAutomaticallyInclude : true, alwaysAutoInsert: true)

This should exist.
Automatic loading of references, and automatic inserting when a parent object is inserted.
(When inserting Customer, all Phone entries are inserted/updated as well).

Why not add this? It would be a great feature to have.
@mbdavid

Hi @rikimaru0345, i will mark this as a suggestion... but I need think better if there some consequences on update/delete cases

If there are any concepts or ideas you have that you want feedback on (maybe if you forgot something or just want to get an outside opinion for proofchecking) let us know :)

Maybe we can also help implementing it if you want...

I think the update-case doesn't really matter as changes can be viewed as remove->add pairs.

When a parent is removed, the children should be removed.
When a child is removed, the parent has to be found and the collection has to be updated to reflect the change.

So maybe alwaysAutoInsert should be changed to autoManageReferences ?
So it will handle delete, add, update of any participating components (child and/or parent).

You can't really have management for auto-insert alone by itself.
You also need auto-update and auto-delete for everything to make sense.
Otherwise it would be really easy to corrupt the db (having orphaned entries, or collections in a parent that don't match up with the children).

What are your thoughts on that @mbdavid ?
I think you are right, this has to be thought through.

@mbdavid
Any updates on this?

@mbdavid
Any update on this or do you know of an alternative implementation?

Hi @gnamse, no update yet. LiteDB still just a database, not an ORM. To implement this, LiteDB must track objects to detect changes (insert/update/deletes).

I think this feature can be implemented in repository pattern layer.... or in an EF implementation.

Was this page helpful?
0 / 5 - 0 ratings