Recursive Delete not working

Issue #12 resolved
Martin Kirsten created an issue

I have a class with two OneToMany relationships, both marked as CascadeOperations=CascadeOperation.All. The inverse ManyToOne relationships are also marked as CascadeOperations=CascadeOperation.All (QUESTION: is it necessary to mark the inverse relationship?).

Here is a (simplified) version of my model classes:

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

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

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

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

    [ForeignKey(typeof(ZoneCollection))]
    public int ZoneCollectionId { get; set; }

    [ManyToOne(CascadeOperations=CascadeOperation.All)]
    public ZoneCollection ZoneCollection { get; set; }
}

public class Room : TagZone
{
    [PrimaryKey, AutoIncrement]
    public int Id { get; set; }

    public string Name { get; set; }
}

When performing a recursive Delete on an instance of TagZoneCollection:

var itemToDelete = Connection.Table<T>().SingleOrDefault (x => x.Guid == guid);
if (itemToDelete != null) {
    Connection.Delete (itemToDelete, recursive: true);
}

I expect that its child Rooms and TagZones will be deleted as well, but they aren't; only the ZoneCollection instance (i.e. the parent) is deleted. I have tracked the issue down to this line in method DeleteAllRecursive() in class WriteOperations:

var value = relationshipProperty.GetValue(element, null);

where value evaluates to null, and the call to

conn.DeleteValueRecursive(value, recursive, objectCache);

therefore does nothing.

Am I doing something wrong?

Comments (3)

  1. Guillermo GutiƩrrez

    Recursive delete will delete objects that are already in memory, but it won't access database to load relationships of objects to delete. So, to sum up, replace this line:

    var itemToDelete = Connection.Table<T>().SingleOrDefault (x => x.Guid == guid);
    

    With:

    var itemToDelete = Connection.FindWithChildren<T>(guid);
    

    And let me know how it goes.

  2. Log in to comment