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.