Intermediate records get deleted with many-to-many relationship

Issue #110 new
Marco Miltenburg created an issue

Note: using 1.3.0

I'm running into a problem where records in the intermediate table get deleted when multiple instances of an object of type A reference the same instances of objects of type B. This is of course the purpose of a many-to-many relationship.

I've duplicated the problem in a NUnit test using some classes from the projects own unit tests.

First of M2MClassA:

        public class M2MClassA
        {
            [PrimaryKey, AutoIncrement, Column("_id")]
            public int Id { get; set; }

            [ManyToMany(typeof(ClassAClassB), CascadeOperations = CascadeOperation.CascadeInsert | CascadeOperation.CascadeDelete)]
            public List<M2MClassB> BObjects { get; set; }

            public string Bar { get; set; }
        }

This is pretty much the same as in the project, except that I added the Insert and Delete cascade operations. These seems to be no problem though.

Then class M2MClassB:

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

            public string Foo { get; set; }

            [ManyToMany(typeof(ClassAClassB))]
            public List<M2MClassA> AObjects { get; set; }
        }

I've added the [ManyToMany] attribute and the property AObjects, these are not in the original class. I wanted this as I wanted to add the Delete cascade operation to make sure that if any entity of ClassB is deleted, all references to it are also deleted. But I never got to adding it as just adding this property and attribute is already causing problems.

The following unit test demonstrates it:

        M2MClassB objectB1 = new M2MClassB()
        {
            Foo = "This is object B #1"
        };

        M2MClassB objectB2= new M2MClassB()
        {
            Foo = "This is object B #2"
        };

        [Test]
        public async Task Adding_Two_Different_M2MClassA_Instances_Referencing_The_Same_M2MClassB_Instances_Should_Not_Delete_Rows_In_Intermediate_Table()
        {
            // Arrange
            M2MClassA objectA1 = new M2MClassA();
            objectA1.Bar = "This is object A #1";
            objectA1.BObjects = new List<M2MClassB>();
            objectA1.BObjects.Add(objectB1);
            objectA1.BObjects.Add(objectB2);

            M2MClassA objectA2 = new M2MClassA();
            objectA2.Bar = "This is object A #2";
            objectA2.BObjects = new List<M2MClassB>();
            objectA2.BObjects.Add(objectB1);
            objectA2.BObjects.Add(objectB2);

            // Act
            await conn.InsertOrReplaceWithChildrenAsync(objectA1, true);
            await conn.InsertOrReplaceWithChildrenAsync(objectA2, true);

            // Assert
            List<ClassAClassB> result = await conn.Table<ClassAClassB>().ToListAsync();

            // We should have four rows, two for A1 referencing B1 and B2, and two for A2, referencing B1 and B2.
            Assert.AreEqual(4, result.Count);
        }

The test fails and reports that it got 2 back instead of 4. The intermediate records between A1 and B1 and B2 are deleted when A2 is added.

Is this a bug or am I doing something wrong?

Comments (0)

  1. Log in to comment