2

Here is some sample code to reproduce the problem:

Customer class

public class Customer
{
    private int _id;

    [Column("_id"), PrimaryKey, AutoIncrement]
    public int Id
    {
        get { return _id; }
        set
        {
            if (value != _id)
            {_id = value;}
        }
    }

   private string _name;

   [Column("_name")]
   public string Name
   {
       get { return _name; }
       set
       {
           if (value != _name)
           {_name = value;}
       }
   }

   private List<Order> _orders;
   [OneToMany(CascadeOperations = CascadeOperation.CascadeInsert | CascadeOperation.CascadeRead | CascadeOperation.CascadeDelete)]
   public List<Order> Orders
   {
       get { return _orders; }
       set
       {
           if (_orders != value)
           {
               _orders = value;
           }
       }
   } 

Order class

public class Order
{
    private int _id;

    [Column("_id"), PrimaryKey, AutoIncrement]
    public int Id
    {
        get { return _id; }
        set
        {
            if (value != _id)
                _id = value;
        }
    }

    private string _name;

    [Column("_name")]
    public string Name
    {
        get { return _name; }
        set
        {
            if (value != _name)
                _name = value;
        }
    }

    private int _customerId;

    [Column("_customerId"), ForeignKey(typeof(Customer))]
    public int CustomerId
    {
        get { return _customerId; }
        set
        {
            if (value != _customerId)
                _customerId = value;
        }
    }
}

DB operations

Customer customer = new Customer(){Name = "Customer One"};
context.InsertWithChildren(customer, true);
customer.Orders = new List<Order>();
customer.Orders.Add(new Order(){Name="Sample order"});
context.UpdateWithChildren(customer);

// get a new copy from the db
var result = context.GetWithChildren<Customer>(customer.Id,true); 

List<Order> orders = result.Orders; // Orders.Count is 0

Am I doing something wrong here or is UpdateWithChildren supposed to work like this?

EDIT

Looks like UpdateWithChildren does not insert a new Orderif one is not present in the DB. Inserting the order first, assigning it to the customer and then calling UpdateWithChildren establishes the relationship.

Customer customer = new Customer(){Name = "Customer One"};
context.InsertWithChildren(customer, true);

List<Order> newOrders = new List<Order>();
newOrders.Add(new Order(){Name="Test order"});
context.InsertAllWithChildren(newOrders,true);

customer.Orders = newOrders;

context.UpdateWithChildren(customer);

var result = context.GetWithChildren<Customer>(customer.Id,true);

List<Order> orders = result.Orders; // Orders.Count is 1

I assume this is how I am supposed to do it?

Ertay Shashko
  • 1,247
  • 2
  • 12
  • 21

1 Answers1

7

As you already noticed UpdateWithChildren doesn't insert any new objects into the database. It just updates the relationships. If you want to Insert or Update objects you can use InsertOrReplaceWithChildren or Insert first the objects and then update the relationships.

Alternatively you can use recursive insert operations:

Customer customer = new Customer(){
    Name = "Customer One",
    Orders = new List<Order>{ new Order(){ Name="Test order" } }
};

// Recursively insert 'customer' and all its orders
context.InsertWithChildren(customer, true);
redent84
  • 18,901
  • 4
  • 62
  • 85
  • is there any reason why you haven't added such functionality yet? (if UpdateWithChildren does not find the children in the DB, insert them then?) InsertOrReplace is ok but it wipes out everything first and then writes everything again which causes performance issues. – Ertay Shashko Jan 19 '15 at 14:35
  • SQLite-Net Extensions is not a fully featured ORM and doesn't keep track of modified or inserted objects. It's the user duty to keep track of these changes, so an `UpdateWithChildren` that inserts the objects into the database will perform the very same operations that `InsertOrReplaceWithChildren`. – redent84 Jan 19 '15 at 14:42