Merging Data In Place

Merging Data In Place

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


lotrij posted on Friday, November 17, 2006

Hi,

I recently downloaded CSLA and have been playing around with the base classes.  I'm only up to Chapter 3 in the book, so I'm not sure how everything works yet, but I wanted to see if something was possible before continuing to read:

Is it possible to merge data into a business object in place (without having to throw out to current business object)?

Here's my scenario: I'm developing various applications where I create hierarchical lists of data to be plugged into grids.  I want to set up timers so that the data in the grid is refreshed continuously.  If I change the DataSource of a grid to a new object, the row expansion will be lost, so I want to be able to merge the data into the grid's current DataSource object.

Is it possible to add to/remove from/edit the items in the list, and afterwards have everything set to be not dirty?  That is, can I force a bunch of changes into the lists of business objects and the business objects and tell them that they are clean (this is assuming that the changes I make will cause the objects to become dirty)?

While I was playing with the base classes I implemented a dummy merge that merged two nearly identical lists of business objects together to see what would happen.  I'm guessing using .Save() on the parent list would cause the changes to be applied, but will it do so through the DataPortal?  I don't want the changes due to the merge to try to be saved back to the database, since I just got the most recent changes.  I want the business object to remove the deleted rows and make any other necessary changes to force itself to be clean after the refresh.

 

Thanks,

Jonathan

RockfordLhotka replied on Friday, November 17, 2006

CSLA doesn't do this by itself, no. The Save() method returns a new object (or at least you should assume it will).

However, you could do it yourself, by overriding the Save() method. The complexity depends on how easily you can remap the results back into your object graph, but the concept is like this:

<Serializable()> _
Public Class Customer
  ' normal fields, properties, etc.

  Public Overrides Function Save() As Customer
    Dim result As Customer = Me.Save()
    If Not ReferenceEquals(Me, result) Then
      ' reload yourself with the data in result
      ' _field1 = result._field1
      ' etc.
    End If
  End Function

End Class

lotrij replied on Friday, November 17, 2006

I'm not sure about all of the details of CSLA yet so I might not be thinking about this correctly.

I figured when my applications run initially, I would get an initial list of business objects.  Then on a timer caused refresh I would figure out the changes (perhaps by getting a whole new temporary set of the business objects to compare against) and manually update my current list of business objects (by changing values, adding objects, and removing objects).  At this point my list of business objects would be up to date, so I would want to force the list and its objects to consider themselves clean, since any changes they would have would have been done by me in code .

Is it possible to override Save()  to confirm the refresh changes (forcing deletes, adds, and edits to actually happen) while not actually trying to do anything about them through the DataPortal ?

 

Thanks,

Jonathan

RockfordLhotka replied on Friday, November 17, 2006

lotrij:

Is it possible to override Save()  to confirm the refresh changes (forcing deletes, adds, and edits to actually happen) while not actually trying to do anything about them through the DataPortal ?



Yes, you can completely override Save() and not use the data portal at all if you'd like. People do this sometimes, when they want to use their own persistence mechanism and entirely avoid the data portal.

There are many other options as well. You could create a "persistence" object in your Save() overload, and put all the data you want to save into that object, and then have it save itself. This can most easily be done using a command object.

Something like this:

Public Overrides Function Save() As Customer
  Dim cmd As New CustomerSaver
  ' load cmd with data to save
  cmd = cmd.Execute
  ' reload your object with data from cmd
  Return Me
End Function

In this case you don't call the data portal yourself at all. But the CustomerSaver object (derived from CommandBase) would use the data portal to move itself to the server so it could coordinate the saving of your data. It would then return to the client with the results, so you could repopulate your object with the results.

Copyright (c) Marimer LLC