Many-to-Many scenario

Oct 28, 2010 at 10:58 AM

Hi

I have a many to many scenario as follows. There are Roles and Users linked via a bridging table. I want to be able to add/remove existing users to a role without ever deleting a user from the database. The way the template currently works creates two problems for this type of scenario.

1. When you add an existing user to the UserList the UserList's IsDirty property will be false since the user in the list is an existing user and is not dirty or new.

2. When you remove a user from the UserList the child is marked as Deleted but I only want the briding table's record to be deleted not the actual user record.

I was able to solve number one by adding and extra piece of code in the many-to-many handling section of the template. But I'm not sure how to handle the second problem. Any suggestions? I'm thinking of somehow indicating that only the collection(bridging table) must be updated and mark the user with some sort of DoNotDeleteNavigationProperty or something.

Any suggestions? 

Coordinator
Oct 28, 2010 at 11:47 AM

I have solved this problem in my project by adding an additional column to the Join table (eg. InsertTime). Working that way, EF creates 3 entities in the model and you handle them like any Parent-child relationship. I'll see what can be done in order to completely support this scenario in CslaExtension.

Oct 28, 2010 at 12:44 PM

I have hacked the template a bit and done what I mentioned in my first post. It required some additional methods on the UserList to remove a user and mark it as a collection remove only. Then in the many-to-many handling code I get a list of these special case removed users and remove them from the EF Users collection which in turn only goes and deletes the record from the bridging table. It's by no way an elagant solution but if you want I can send you the modifed template.

 

 

 

Coordinator
Oct 28, 2010 at 12:59 PM

I'll see how this can be solved because it's not a simple task. 

There are two scenarios with Many-to-many relationships:

1. Relationship when both related entities are saved independently to the database, and join table only connects those entities: this is your scenario

2. Relationship when one entity is Parent and other is child, and children are saved within parent's transaction: for example if you have table two tables "Documents1" and "Documents2", and a table DocumentValues which serves for storing values for all document types. In that case you have two join tables "Documents1_DocumentValues" and "Documents2_DocumentValues". In this scenario you really want to delete record from join table and also from the DocumentValues table when it's removed from parents list. (I hope this is not very confusing).

In order to support your scenario, I must add logic for removing child entity from parent's list and not deleting it from the database. In the second scenario this is not the case, so I must find a way to support both scenarios. 

Let me think about this issue and I'll probably find a solution. If you have any idea how this can be solved, feel free to contact me.

You can make changes to the T4 file in order to continue your work now.

Regards,

Josip

 

Developer
Oct 28, 2010 at 1:16 PM

Hi,

The author of the CSLA framework has stated many times that many to many relationships should not be reflected at the object level, even though they are required at the relational level (ie in the database) in M:M relations.

When designing your use-case, you should concentrate on behavior, not data. You should avoid trying to have large "do-it-all" objects and rather aim for small "one-concern" objects. This way you can avoid pushing the M:M relation up into your BO layer.

That is, IMHO, what Rocky teaches in his books/videos, so I don't know if tools should try to support a scenario that is not really supported by the framework itself.

Regards

Coordinator
Oct 28, 2010 at 8:55 PM

Hi Luc :)

I agree with you, this issue is something that can be avoided by using small object that is used only for that scenario. And that is probably a better solution in many cases.

However, Lhotka also says that nothing should be considered as a rule, but as a guidance. So, if you can solve some problem in a better way using inheritance or many to many relationship, I think you should do it. I also think that you should not make compromises in your design based on framework or tool limitations.

 @ktersius:

There is no easy fix for this. I will add this issue to our IssueTracker.

Possible solution using current version:

Lets say you have two objects: Parent and Child. Parent contains collection of Children objects. You should implement Parent's partial methods AfterInsert and AfterUpdate where you can edit data entities in order to remove or add child to the parent. Code should look like this:


public partial class Parent
{
   partial void AfterInsert(Data.Parent data)
   {
      foreach (var child in this.Children)
      {
          if (child.IsNew)
             //add child data to parent data
          if (child.IsDeleted)
             //remove child data from parents data
          
          //child.MarkClean() in order not to save to the DB
      }
   }
}
 

Coordinator
Oct 28, 2010 at 9:35 PM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.
Nov 8, 2010 at 3:11 PM
Edited Nov 8, 2010 at 3:12 PM
ktersius wrote:

I have hacked the template a bit and done what I mentioned in my first post. It required some additional methods on the UserList to remove a user and mark it as a collection remove only. Then in the many-to-many handling code I get a list of these special case removed users and remove them from the EF Users collection which in turn only goes and deletes the record from the bridging table. It's by no way an elagant solution but if you want I can send you the modifed template.

Could you send me your hacked template, we are trying to find a solution over here without success.