Object is still being edited and can not be saved

Object is still being edited and can not be saved

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


gmclean posted on Thursday, June 01, 2006

I am obviously missing something simple.

I have a windows form tied to an Editable Root business object. The business object had a number of child objects and all was working well. Some of the child objects were just lookup lists so I took them out of the BO and created separate objects in the form load event. When I did this the save stopped working (when I make data changes) and I get the message "Object is still being edited and can not be saved". EditLevel is 1 when I get this error.

I have tried to set everything back so the BO has no children and the form only is tied to the BO, no lookup lists. I still get the error.

Any suggestions on where to start looking?

Thanks

George

xal replied on Thursday, June 01, 2006

George,
you need to call yourBo.ApplyEdit()
This is because of the nlevel undo feature. You need to call ApplyEdit as many times as you called BeginEdit. It sounds as if you did not call BeginEdit yourself, which is probably because the binding manager calls BeginEdit automatically.


Andrés

RockfordLhotka replied on Thursday, June 01, 2006

The lookup lists shouldn't be child objects of an editable root. At least in every case I've encountered lookup lists are a form of using relationship and the business object merely contains them as a convenience (well, that and so the object properties associated with the lookup key values can be validated within the object - that's quite important!).

Are you calling EditableRootBindingSource.EndEdit to end the editing of the object before calling Save? You must do that, or call ApplyEdit, to get the edit level down to 0. Data binding will automatically call BeginEdit once, so you must end the edit session - the EndEdit call is the best approach.

gmclean replied on Friday, June 02, 2006

Thanks for suggestions.

I added the BO.ApplyEdit before calling save and now I can save changes. What puzzles me is that I was able to update data without ApplyEdit at one point before adding all the child objects (I am not sure at what point it stopped working).

I think I understand the concept of not making the lookup lists children of the editable root but including then in the BO. However, I am not sure I am coding correctly to acheive this.

In my editable root BO if I declare a private member for a list like:

Private mTypeList As LookupList = LookupList.GetList()

where LookupList is a ReadonlyCollectionBase object and then I declare a public member as

    Public ReadOnly Property TypeList() As LookupList
        Get
            Return mTypeList
        End Get
    End Property

Am I creating this as a child of the editable root? I get strange behavior with this where I need to tab twice to get out of any field where the data changes. The Set of the bound property of the field that is changed does not fire unitl the second tab so I am not sure what is happening on the first tab since I can not trace any code.

If I create a separate lookup list in the form instead of the BO class then I do not see this behavior and all appears to work. I would continue with this method except for Rocky's comments above about validating the lookup list against the objects properties associated with the list. It appears to me that the validation is occuring even when the lookup list is not part of the BO.

Any suggestions in understanding this would be appreciated!

Thanks

George

RockfordLhotka replied on Friday, June 02, 2006

If you implement LookupList.GetList() to cache the results then you can simplify your BO code a lot - to just this:
 
Public ReadOnly PropertyTypeList() As LookupList
  Get
    Return LookupList.GetList()
  End Get
End Property
 
This will trigger retrieval of the lookup data just once, assuming GetList() is implemented along this line:
 
Private Shared mList As LookupList
 
Public Shared Function GetList() As LookupList
  If mList Is Nothing Then
    mList = DataPortal.Fetch(Of LookupList)(New Criteria(GetType(LookupList))
  End If
  Return mList
End Function
 
This technique avoids any extra serialization of the lookup list data back and forth through the data portal, and centralizes the caching in one place.
 
Rocky

gmclean replied on Friday, June 02, 2006

Rocky,

Your suggestion for simplifying the lookup lists seems to have solved the problem. I really appreciate the help!

George

Copyright (c) Marimer LLC