2010-08-20 55 views
2

我想要更改所有匹配条件的对象以使用特定/新的子类。使用子类的实例替换db4o存储的对象

没有其他的子类用于存储对象,所以它在所有情况下都是从基类到其子类的变化。

为了保持指向这些对象的所有引用,我尝试使用bind将它们替换为子类的新实例(复制所有数据),但它似乎将其限制仅限于相同特定类的项目。

有没有办法做到这一点,不需要添加代码来显式更新指向这些对象的每个引用?将一个对象的所有引用替换为另一个对象的单个调用将会很棒。

回答

4

好问题。据我所知这是不可能的=(。唯一的办法是将数据复制到新的类型

正如你所说,当你将数据复制到新的类型,你有问题有很多引用指向旧实例,而不是新实例,绑定实际上会检查类型

这不会让任何选项只能应对和更新所有引用,这当然是一个繁琐的过程。=(因此,查询所有需要更改类型的对象,将数据复制到新对象中,然后查询引用旧对象的所有对象,并替换参考对象

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); 
} 

不要忘记替换集合和数组中的引用。

Btw。我想我周围有一些代码分析类型并找到引用其他类型的属性并找到它的对象。如果有帮助?

现在到另一种可能的方式来做到这一点,如果你喜欢冒险:改变一下db4o代码。因为您想要将对象更改为子类型,所以将它绑定到新对象应该是安全的。所以如果现有的对象突然指向新的子类型,它仍然应该工作。那么,你可以做什么来删除Bind-Method-implementation中的检查并尝试运行它。

+1

+1 @Gamlor我现在这样做(复制+查询/更新所有引用),感觉很糟糕,所以我希望以某种既定方式查询/更新指向该对象的所有引用。最后,在我的场景中没有太多的参考资料(约6)。我会留下这个问题,对此有任何其他反馈意见。 – eglasius 2010-08-21 16:46:43

+2

我同意,更好的方法会非常好。 – Gamlor 2010-08-21 18:27:55