Multiple Add/Remove from a BusinessListBase

Multiple Add/Remove from a BusinessListBase

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


MBursill posted on Monday, November 08, 2010

 

My object graph

ShoppingCart
        |___ Products (contains "Test Product A")
                        |____ Product

When the object graph is first fetched, Products contains product A. The user then navigates the UI and removes product A from the products list. Later, before saving, the user decides to re-added product A.

In short, product A started and ended in the list, despite X number of add/remove instances triggered by the user. The end result is the same as the starting result, so no insert or delete is necessary.

The "IsNew" of product A was originally false. When added back a second time I check for an existing product (using an IEqualityComparer) in the deleted list and do not issue a create (only a fetch child). Therefore product A is added to the products list with the IsNew still set to false.

The problem is, a save against the root object causes product A to call delete self.

I understand this is happening because an instance of product A exists in the products deleted list, however, I don't know how to avoid that.

What would be ideal is for CSLA's collection types to contain an IEqualityComparer<ChildType> property. When Save is called, the IEqualityComparer could be used to compare the objects of the deleted list against the objects of the current list to determine if it is necessary to call DeleteSelf.

I can't be the first person to encounter this scenario. Am I going about it the wrong way? What's the "best practice" for this type of requirement? Thanks,

-Mike.

 

RockfordLhotka replied on Monday, November 08, 2010

BusinessListBase is designed to "undelete" items through the CancelEdit mechanism. It isn't really designed around the idea that you'd delete an item and then add "that same item" into the list (since that has no meaning really does it?).

CSLA used to have a "logical equality" concept, but WPF data binding really messed with that - it likes reference equality only.

However, you can accomplish your scenario by overriding Child_Update. The default implementation is pretty straightforward:

    protected virtual void Child_Update(params object[] parameters)
    {
      var oldRLCE = this.RaiseListChangedEvents;
      this.RaiseListChangedEvents = false;
      try
      {
        foreach (var child in DeletedList)
          DataPortal.UpdateChild(child, parameters);
        DeletedList.Clear();

        foreach (var child in this)
          if (child.IsDirty) DataPortal.UpdateChild(child, parameters);
      }
      finally
      {
        this.RaiseListChangedEvents = oldRLCE;
      }
    }

But you could easily add a little extra code in the loop through DeletedList to not process any items that you decide are actually in the active list.

RockfordLhotka replied on Monday, November 08, 2010

It also occurs to me that you can override InsertItem to accomplish your goal, in perhaps a more efficient way.

Just override the method, call the base implementation to actually do the insert, and then remove the "duplicate item" from DeletedList.

Copyright (c) Marimer LLC