1

I am using SQLite-Net PCL together with SQLite-Net extensions for the development of an application using Xamarin.

In my model I have an entity (let's call it A) which is connected to other four entities through one-to-many relationships (that are represented as lists in the model). In order to populate the tables recursively when inserting an object of A in the database I have defined the relations to use Cascade on both read, insert and delete.

In order to test if I did everything correctly I created an object of type A and populated the including lists, and finally I have inserted it into the database. The strange thing is that, for 2 of the 4 including lists the insertion went well, and all the connected objects are inserted. For other 2, instead, only the first object of the list is inserted in the database. To be clear, I am checking the database content directly with a db browser.

The following is an example of one of the objects for which only the first element of the list is inserted.

public class Username : Entity
{
    public string Name
    {
        get;
        set;
    }

    [ForeignKey(typeof(A))]
    public int AId
    {
        get;
        set;
    }

    public Username(string username)
    {
        Name = username;
    }
}

This is instead one of the objects for which the insertion is correct.

public class AnAddress: Entity
{

    public string Address
    {
        get;
        set;
    }

    public AddressType Type
    {
        get;
        set;
    }

   [ForeignKey(typeof(A))]
    public int AId
    {
        get;
        set;
    }
}

To be clear, the base object Entity contains the definition of the primary key:

public abstract class Entity
{

    [PrimaryKey, AutoIncrement]
    public int Id
    {
        get;
        set;
    }

    public Entity()
    {
        Id = -1;
    }

}

And this is the way the relationships are defined:

public class A : Entity
{

    public string Name
    {
        get;
        set;
    }

    [OneToMany(CascadeOperations = CascadeOperation.All)]
    public List<AnAddress> Addresses
    {
        get;
        set;
    }

    [OneToMany(CascadeOperations = CascadeOperation.All)]
    public List<Username> Usernames
    {
        get;
        set;
    }
}

I then create an A object by initialising it with two lists (List and List) in the same identical way. I finally insert the object in the database with

c.InsertWithChildren(entity, recursive: true));

Where entity is of type A and c is the connection object.

Do you have any clue about the motivation of this strange behaviour?

papafe
  • 2,959
  • 4
  • 41
  • 72
  • Can you show the primary key and relationship properties and the code that you use for inserting the objects? The `Equals` and `GetHashCode` methods are irrelevant. – redent84 Mar 12 '15 at 16:45
  • Added the information you were asking for. As a side note, I would also expect the `Equals` and `GetHashCode` to be irrelevant, but actually I was getting a, very expressive I must say, Exception which message was "Constraint" when I had the Equals method on the `Username` class – papafe Mar 12 '15 at 18:03
  • Have you tried inserting the objects manually using `Insert` and then call `UpdateWithChildren` on the `entity` object? Maybe this will bring some light to the issue. A sample project reproducing the issue would be very helpful. – redent84 Mar 13 '15 at 08:42
  • 1
    Actually I've managed to solve the issues. Unexpectedly, the issues was with the `Equals` method. Both the entities that had problems with inserting didn't have implemented the equals method, so the one of the base class was used. In this case two object were considered equal if they had the same `Id`, that was set to one automatically on creation. I have made some tests, and it seems that if two objects on the list are considered equal, only the first one is inserted and the second one is not. Probably a more explicit error would have been useful in this case :) – papafe Mar 13 '15 at 09:41
  • Recursive inserts try to perform as few operations as strictly required, so we keep track of the inserted elements and compare them to avoid adding duplicated records. Maybe overriding the equals method is impacting negatively in this behavior. – redent84 Mar 13 '15 at 10:51
  • Well, it is good that now I know it and I can fix it :) – papafe Mar 13 '15 at 11:22

0 Answers0