Замена хранимого объекта db4o экземпляром подкласса - PullRequest
2 голосов
/ 20 августа 2010

Я хочу изменить все объекты, которые соответствуют условию, для использования определенного / нового подкласса.

Нет других подклассов, используемых с сохраненными объектами, поэтому во всех случаях это переход от базового класса к его подклассу.

Чтобы все ссылки указывали на эти объекты, я попытался использовать bind , чтобы заменить их новыми экземплярами подкласса (копировать все данные), но, похоже, привязка ограничена только элементами тот же конкретный класс.

Есть ли способ сделать это, не требующий добавления кода для явного обновления каждой ссылки, которая указывает на эти объекты? Один вызов, который заменяет все ссылки из одного объекта в другой, был бы хорош.

1 Ответ

4 голосов
/ 21 августа 2010

Хороший вопрос. Насколько я знаю, это невозможно = (. Единственный способ - скопировать данные в новый тип.

Как вы сказали, когда вы копируете данные в новый тип, у вас возникает проблема, что есть много ссылок, которые указывают на старый экземпляр вместо нового экземпляра. И 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);
}

Не забудьте заменить ссылки в коллекциях и массивах.

Btw. Я думаю, что у меня есть некоторый код, который анализирует типы и находит свойства, которые ссылаются на другой тип и находят объект для него. Если это поможет?

Теперь к другому потенциальному способу сделать это, если вы готовы к приключениям: немного измените код db4o. Поскольку вы хотите изменить объекты на подтип, можно с уверенностью «связать» его с новым объектом. Поэтому, если существующий объект внезапно указывает на новый подтип, он все равно должен работать. Итак, что вы можете сделать, чтобы убрать проверку в реализации Bind-Method и попытаться запустить ее.

...