tags:

views:

39

answers:

1

I want to change all objects that match a condition to use a specific/new subclass.

There are no other subclasses being used with the stored objects, so its in all cases a change from the base class to its subclass.

In order to keep all references pointing to these objects, I tried using bind to replace them with new instances of the subclass (copying all the data), but it seems bind its restricted only to items of the same specific class.

Is there any way to do this that doesn't require adding code to explicitly update every reference that points to these objects? A single call that replaces all references from one object to another would be great.

+2  A: 

Good question. As far as I know this isn't possible =(. The only way is to copy the data over to the new type.

As you said, when you copy the data over to the new type, you have the issue that there are lots of references which point to the old instance instead of the new instance. And bind indeed checks the type.

This leaves no option but coping and updating all references, which is of course a tedious process. =( So query for all object you need to change the type. Copy the data to the new object. Then query for all object which reference to the old object and replace the reference.

IObjectContainer container = ... //
foreach(var oldObject in container.Query<MyType>())
{
     NewSubType newCopy = copyToSubType(oldObject); // copy the data

     var referencesFromTypeA = from TypeA a in container
                               where a.ReferenceToMyType == oldObject
                               select a
     // repeat this for all types which can refer to the object which are copied
     // it can certainly be generified
     foreach(var referenceToUpdate in referencesFromTypeA)
     {
            referenceToUpdate.ReferenceToMyType=newCopy;
            container.Store(referenceToUpdate);
     }
     container.Store(newCopy);
     container.Delete(oldObject);
}

Don't forget to replace the referenced in collections and array.

Btw. I think I've some code around which analyses the types and finds properties which refer to another type and find the object for it. If it helps?

Now to another potential way to do it, if your up for adventures: Change the db4o code a little. Because you want to change the objects to a subtype, it should be safe to 'Bind' it to the new object. So if the existing object suddenly point to the new subtype, it still should work. So what you could do it to remove the check in the Bind-Method-implementation and try to run it.

Gamlor
+1 @Gamlor I'm doing it that way now (copying + querying/updating all references), feels awful so I was hoping for some established way to query/update all the references that point to the object. At the end there weren't so many references in my scenario (about 6). I'll leave the question open for a bit, for any other feedback on this.
eglasius
I agree, a better method would be really nice.
Gamlor