Получить объект в одном сеансе DB4O, хранить в другом («Отключенный сценарий»)
-
27-10-2019 - |
Вопрос
Я пытаюсь выяснить, как сохранить удобный объект между сеансами клиента в DB4O. Из того, что я понимаю, после закрытия клиентского сеанса объект больше не проживает ни в каком кэше, и, несмотря на то, что у меня есть действительный UUID, я не могу позвонить в него, не вызывая дубликата. Я искал способ вручную повторно добавить его в кеш, но такого механизма нет. Повторное переоборудование заставит меня скопировать все значения от ныне бесполезного объекта.
Вот приведенный выше абзац в коде:
Person person = new Person() { FirstName = "Howdoyu", LastName = "Du" };
Db4oUUID uuid;
// Store the new person in one session
using (IObjectContainer client = server.OpenClient())
{
client.Store(person);
uuid = client.Ext().GetObjectInfo(person).GetUUID();
}
// Guy changed his name, it happens
person.FirstName = "Charlie";
using (var client = server.OpenClient())
{
// TODO: MISSING SOME WAY TO RE-USE UUID HERE
client.Store(person); // will create a new person, named charlie, instead of changing Mr. Du's first name
}
Последняя версия Eloquera поддерживает эти сценарии, либо через атрибут [ID] или через магазин (UID, Object).
Какие-нибудь мысли?
Решение 2
Хорошо, ответ Гамлора о методе db4o iextcontainer.bind () указал мне на решение. Обратите внимание, что это решение действителен только в очень конкретных ситуациях, когда доступ к БД тесно контролируется, и никакие внешние запросы не могут получить экземпляры объекта.
Предупреждение: это решение опасно. Анкет Он может заполнить вашу базу данных всевозможными дубликатами и мусорными объектами, потому что заменяет объект и не обновляет свои значения, поэтому нарушая на него ссылки. Нажмите здесь, чтобы получить полное объяснение.
ОБНОВИТЬ: Даже в строго контролируемых сценариях это может вызвать бесконечные головные боли (например, у меня сейчас) для чего -либо, кроме плоского объекта только с свойствами типа значения (строка, инт и т. Д.). Если вы не можете спроектировать свой код для извлечения, отредактировать и сохранить объекты в одном соединении DB4O, то я вообще не рекомендую использовать DB4O.
Person person = new Person() { FirstName = "Charles", LastName = "The Second" };
Db4oUUID uuid;
using (IObjectContainer client = server.OpenClient())
{
// Store the new object for the first time
client.Store(person);
// Keep the UUID for later use
uuid = client.Ext().GetObjectInfo(person).GetUUID();
}
// Guy changed his name, it happens
person.FirstName = "Lil' Charlie";
using (var client = server.OpenClient())
{
// Get a reference only (not data) to the stored object (server round trip, but lightweight)
Person inactiveReference = (Person) client.Ext().GetByUUID(uuid);
// Get the temp ID for this object within this client session
long tempID = client.Ext().GetID(inactiveReference);
// Replace the object the temp ID points to
client.Ext().Bind(person, tempID);
// Replace the stored object
client.Store(person);
}
Другие советы
Эта функциональность действительно отсутствует в DB4O = (. Это делает DB4O очень трудным в использовании во многих сценариях.
Вы в основном должны написать свой собственный метод reattach, преодолев все атрибуты. Может быть, такая библиотека, как Automapper, может помочь, но в конце концов вы должны сделать это самостоятельно.
Другой вопрос заключается в том, действительно ли вы хотите использовать UUIDS DB4O для определения объекта. DB4O Uuids огромны и не известный тип. Я лично предпочел бы регулярные .NET GUID.
Кстати: есть метод db4o .bind (), который связывает объект с существующим идентификатором. Однако это вряд ли делает то, что вы действительно хотите. Я думаю, что вы хотите хранить изменения, внесенные в объект. Свяжите в основном заменяет объект и разбивает график объекта. Например, если у вас есть частично загруженные объекты, а затем связываете его, вы теряете ссылки на объекты. Так что .Bind не пригодна для использования.