【发布时间】:2010-08-20 18:35:26
【问题描述】:
我想更改所有符合条件的对象以使用特定/新的子类。
没有与存储对象一起使用的其他子类,因此在所有情况下,它都是从基类到其子类的更改。
为了保持所有指向这些对象的引用,我尝试使用bind 将它们替换为子类的新实例(复制所有数据),但它似乎只将其绑定到同一特定类的项目.
有没有什么方法不需要添加代码来显式更新指向这些对象的每个引用?将一个对象的所有引用替换为另一个对象的单个调用会很棒。
【问题讨论】:
我想更改所有符合条件的对象以使用特定/新的子类。
没有与存储对象一起使用的其他子类,因此在所有情况下,它都是从基类到其子类的更改。
为了保持所有指向这些对象的引用,我尝试使用bind 将它们替换为子类的新实例(复制所有数据),但它似乎只将其绑定到同一特定类的项目.
有没有什么方法不需要添加代码来显式更新指向这些对象的每个引用?将一个对象的所有引用替换为另一个对象的单个调用会很棒。
【问题讨论】:
好问题。据我所知,这是不可能的 =(。唯一的方法是将数据复制到新类型。
正如您所说,当您将数据复制到新类型时,您会遇到很多引用指向旧实例而不是新实例的问题。而且 bind 确实会检查类型。
除了处理和更新所有引用之外别无选择,这当然是一个乏味的过程。 =(所以查询所有需要更改类型的对象。将数据复制到新对象。然后查询引用旧对象的所有对象并替换引用。
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);
}
不要忘记替换集合和数组中的引用。
顺便说一句。我想我有一些代码可以分析类型并找到引用另一种类型的属性并找到它的对象。如果有帮助?
如果您愿意冒险,现在换一种可能的方法:稍微更改 db4o 代码。因为您要将对象更改为子类型,所以将其“绑定”到新对象应该是安全的。因此,如果现有对象突然指向新的子类型,它仍然应该工作。那么你可以做些什么来删除 Bind-Method-implementation 中的检查并尝试运行它。
【讨论】: