Remove vs Delete in BusinessCollectionBase (v1.5)

Remove vs Delete in BusinessCollectionBase (v1.5)

Old forum URL: forums.lhotka.net/forums/t/2056.aspx


kayakheaven posted on Monday, January 01, 2007

I'm using CSLA v1.5 to implement two collections containing the same child class. I want to move object instances from one collection to the other and save / update to persist the changes. So I write

col1.Remove(obj1);

col2.Add(obj1);

col1.Save();

col2.Save();

I don't want col1 to try to delete obj1 from the database, but I do want col2 to update it. BusinessCollectionBase doesn't work this way, .Remove leads to a delete from persistent storage.

Looks like I could achieve this enhancement by extending BusinessCollectionBase.OnInsert to check if object val _isDeleted and resetting that flag and separately purge the object instance from col1.deletedList, or implementing a new method .RemoveNoDelete that provides this behavior. Too bad System.Collections.IList doesn't distinguish between Remove and Delete.

Does anyone have any comments on this, am I on the right track or off base?

Brian Criswell replied on Monday, January 01, 2007

What are you trying to do from a business object standpoint (i.e. what scenario is this technical solution trying to fulfill)?  It may be possible that a different technical solution would work better here, such as applying a pair of filters to the same underlying list, one showing the unaltered items and the other showing the moved items.

kayakheaven replied on Monday, January 01, 2007

Hi Brian, thanks for your interest, here is my scenario: RegionalOffices collection contains Office objects which each contain LocalOffices collection each of which contains Office objects. These are displayed in a UI screen, e.g. two linked grids or a hierarchical grid. User can promote a local office to be a regional office or vice versa demote regional office to local office.

In either case I want to remove the office object from its current collection and add it to the other collection, without the object being considered "deleted" since it isn't. The office object properties modified as a result of this move are "is regional office" and "parent regional office code".

Yes I could use a hidden master Office collection that is filtered to obtain the RegionalOffices collection and each child LocalOffices collection, but that seems less intuitive than removing from one collection and adding to the other and having the interals manage that. Shouldn't there be a difference between Remove and Delete?

Brian Criswell replied on Monday, January 01, 2007

From a .NET framework perspective there is only IList.Remove().  So Rocky made BusinessCollectionBase do what would work in 99% of the cases.  So you have two options here:
  1. Modify the framework.
  2. Modify your objects.
It is something that many people run into at some point or another.  I think that if you searched for a bit you could even find a discussion in the forums discussing a similar issue to what you are experiencing.

This seems similar to discussions that pop up every so often where someone has made an object that does two different things because the data is so similar.  However, the behaviour is different, and it is conceptually slightly different.  Only regional offices can have local offices whereas local offices cannot have there own local offices.  This suggests at least three different objects:
However, that does not solve the issue of being able to promote and demote offices.  So the object model changes slightly:
This allows you to have a single OfficeCollection that contains all of your objects.  A RegionalOffices filter shows only the Office objects that are marked as regional.  Another filter LocalOffices would give the option of adding a local office to the list of offices for a regional office.  The Office object would have a Promote() and Demote() methods coupled with CanPromote and CanDemote properties.  CanPromote would return true for local offices.  CanDemote would return true for regional offices that had no local offices.  The corresponding methods would throw InvalidOperationExceptions when they were run and their corresponding properties returned false.

Obviously this example does not exactly fill your need, but hopefully it gives you some ideas as to other options you could choose.  Their are other people on these boards who are better than I at designing objects based on use cases, but I think most of them are still on holiday over the new year.  If you do decide to go about modifying the framework, I would suggest instead that you look at how The CSLA collection base classes handle OnRemove and RemoveAt.  You could have your OfficeCollection override one or both of those methods to have it avoid marking the removed object for deletion.

ajj3085 replied on Tuesday, January 02, 2007

A regional office doesn't sound the same as a local office.  Moving the object from one list to another doesn't sound like the proper way to do this.  Instead, there should be a method that promotes the local office to the regional office.  This might have to be done outside any existing buisiness objects, and would probably have to force a reload of the object being edited.

HTH
Andy

pelinville replied on Friday, January 05, 2007

I often want to remove an object without deleting it.  Especially in my one to many or many to many cases.
 
I have this little method in a subclass.
 

Public Overridable Sub Exclude(ByVal item As SFBusinessBase)

   If item Is Nothing Then Return

      Dim itemMarkedDeleted As Boolean = item.IsDeleted

     If Me.List.Contains(item) Then

         Me.List.Remove(item)

      End If

      Me.deletedList.Remove(item)

'If this item was not marked for deletion before the above calls then unmark it for deletion.

'Otherwise keep it as it was since something else marked it for a reason.

      If Not itemMarkedDeleted Then item.SetNotDeleted()

End Sub

 
 
The SetNotDeleted is in a derived class of BusinessBase and all it does is set the deleted variable to false.
 
 
 

Copyright (c) Marimer LLC