Skip to content

Documentation

Daniel Svensson edited this page Apr 17, 2019 · 1 revision

Implementation notes about creating a new m2m relation in Silverlight

To create a new M2M relation between two entities A and B we can either use the A.Bs.Add or B.As.Add method. This will raise an INotifyCollectionChanged on both entity collections A.Bs and B.As.

Under water a new A_B join table entity is created. This is the entity that represents the m2m relation and which is communicated to the server. To create the m2m relation the navigation properties A and B of the join table entity are used. Setting a navigation property will immediately generate an INotifyCollectionChanged event on the entity collection.

For example: Given an entity 'a' of type A and 'b' of type B and a join table entity 'ab' of type A_B, setting ab.A to a, will raise an INotifyCollectionChanged event on a's entity collection for A_B entities.

The NotifyCollectionChangedEventArgs will contain the newly created join table entity ab. At that moment the value of ab.B is still null! Consequently, it is not possible to determine the other end of the new m2m relation in the event handler!

To deal with this, the client-side generator of m2m4ria creates two special methods in the class AB to set the A and B properties in such a way that an INotifyCollectionChanged event is raised only when both navigation properties have been set. There are two similar methods generated: AttachAToB and AttachBToA. They will do the following (taking AttachAToB as an example):

First the EntityRef for A r._A is initiated by reading the A property of the join table entity r

Then the 'a' entity is assigned to this entity ref, and the foreign key property for 'a' is assigned the value of a.AId. From this moment on r.A and r.AId are initialized without generating an INotifyCollectionChanged event.

No we can set the r.B property. This will raise an INotifyCollectionChanged property, where both r.A and r.B are not null.

We now reset the r._a.Entity and r._aId (this will raise no INotifyCollectionChanged event)

Finally we set r.A which again raises an INotifyCollectionChanged event. Again both navigation properties have a value.