Version: 1.0.2005
We have a Parent object with a 1:1 relation with a Child. We load the Parent and subsequently reference the Child, such as this:
dim localChild as ChildEntity = parentReference.Child
This allows us to work with "localChild", but if any subsequent code references parentReference.Child again, the internal "GetSingleChild(False)" in the Parent object will be executed again, and since the member variable _alreadyFetchedChild is False, the child is refetched from the database. Since it does not exist, this causes a new child to be created and passed to the setter for the Child() property. This fires SetupSyncChild(relatedEntity). We note that the Set part of the Child() property calls down into SetupSynchChild(relatedEntity). SetupSyncChild() then sets _alreadyFetchedChild to true. However, the code in GetSingleChild() immediately sets _alreadyFetchedChild = fetchResult. In effect, this results in the following sequence of behavior:
1.) Since _alreadyFetchedChild = False, any reference to the Child() property getter will cause a new child object to be loaded from the store
2.) fetchResult = false in GetSingleChild(), since the child does not exist in the store
3.) GetSingleChild() calls the setter for the Child() property like so:
Me.Child = newEntity
4.) The setter then executes this sequence:
Dim relatedEntity As IEntity = CType(value, IEntity)
relatedEntity.SetRelatedEntity(Me, "Child")
SetupSyncChild(relatedEntity)
5.) SetupSyncChild() sets _alreadyFetchedChild to True
6.) Immediately thereafter, GetSingleChild() does this:
_alreadyFetchedChild = fetchResult
This causes a nasty side effect in the code, whereby we continue to work with our localChild reference, thinking that it is the same object as Parent.Child, but other code that leverages the object graph in the meantime may reference the Child(), causing it to reload, and now the reference that we hold in localChild() is, in effect, "disconnected" from the Parent, and the Parent now has a new Child, which it will not save to the store!!!!
Questions:
1.) Why must repeated references to Parent.Child() result in the reloading of Child() each and every time, even if we have set properties on Child, and Child is plenty dirty?
2.) We can see in the comments that the Parent.Child() property is for convenience only, and that we should use GetSingleChild(). Why is this so? It seems to exhibit the same behaviors.
3.) Assuming that we do get an object reference back from GetSingleChild() or from Parent.Child(), how can we tell that the internal fetch failed and that we need to assign a new object reference to the Parent.Child property in order to have it stop reloading? What is the best practice here? In our use case, we need to check whether or not the Child has been assigned yet, and if not, create one. However, since the generated code does not return a Null reference, we seem unable to do so.
4.) As a last question, why does the Child not save to the store in cases of fetch failure? There is an object reference there, and it IsNew, and IsDirty, so why is it not being persisted during recursive saves? What prevents it from being saved?
Regards,
Cardplayer