C63d2d886af30dbea99a341467ac116d

.Net, C#

The code below is called when an object (classificator) is scheduled to delete.
First it is deleted from memory by removing all references to other objects,
Second, undo action is added to restore references to other objects
Third, an action to save changes to database is added

manager.UndoManager holds all save actions, and all undo actions.

The most embarrasings lines are the first three lines in while loop.
foreach loop can not be used in this implementation, since when references are removed (client.Area = null;), a collection is changed (classificator.Clients), and thus foreach can not be used.

For that i use while count > 0, get first object, and remove all asociations from it.

1
2
3
4
5
6
7
8
while (classificator.Clients.Count > 0)
{
	Client client = ServiceHelper<Client>.GetFirst(classificator.Clients);
	client.Area = null;
	EventHandler handler = delegate {client.Area = classificator;};
	manager.UndoManager.AddUndo(new DelegateMemento(handler));
	manager.UndoManager.AddSaveAction(new SaveToDatabase(client));
}

Refactorings

No refactoring yet !

4d1c9dad17af98e55cb65b4efce27c42

Ben Burkert

September 27, 2007, September 27, 2007 10:09, permalink

1 rating. Login to rate!

Maybe use a revision system in the database instead of a undo system in memory. Keeping the undo's as delegates is volatile and a memory hog. Revisions would allow you to do something like this:

1
2
3
4
5
6
7
8
9
OrmManager ormManager = OrmManager.Current;

RevisionManager.CreateRevision(ormManager, delegate
  {
    foreach(client as Client in classificator.Clients)
      client.ResetArea();

    classificator.MarkAsDeleted();
  });

Then rollback/migrate the database

1
2
3
4
5
6
RevisionManager.RollbackTo(1, ormManager);
classificator = ormManager.findClassificator("classificator name");

RevisionManager.MigrateTo(RevisionManager.Latest, ormManager);
classificator = ormManager.findClassificator("classificator name");
C63d2d886af30dbea99a341467ac116d

Darius Damalakas

September 28, 2007, September 28, 2007 00:30, permalink

No rating. Login to rate!

An interesting suggestion to keep revisions in database.
I just want to clarify: when does the actual insert into databse occurs? is it in classificator.MarkAsDeleted(); or RevisionManager.MigrateTo(..) ?

We have to keep undo's in memory. Take this scenario for example:
1. I open company window for editing.
2. I change company name, and company address
3. Then i see the tab with a list of clients.
4. I press "Create" to add a new client to the company
5. [The company window changes still do not go to database.]
6. A client window opens showing client properties (such as name, surname, location, area, etc.)
7. I enter whatever data i need
8. I press button save and then i close the window.
8.5 In company window now i see one client
9. [Still nothing goes to database, since client window was "a child" of company window]
10. Then i can either press save on company window and thus the changes will actually go to databse, or i can press exit window button, and tell to discard changes.

However, you example is nice to keep track of change history. Thanks!

Your refactoring





Format Copy from initial code

or Cancel