1

我试图弄清楚如何在 DB4O 中的客户端会话之间保持对象可用。据我了解,一旦客户端会话关闭,该对象就不再驻留在任何缓存中,尽管我有一个有效的 UUID,但我无法在它上面调用 Store 而不导致插入重复项。我搜索了一种手动将其重新添加到缓存中的方法,但没有这种机制。重新检索它将迫使我从现在无用的对象中复制所有值。

这是上面的代码段:

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] 属性或通过 Store(uid, object) 支持这些场景。

有什么想法吗?

4

2 回答 2

1

db4o =( 中确实缺少此功能。这使得 db4o 在许多场景中都很难使用。

您基本上必须通过处理所有属性来编写自己的重新附加方法。也许像 Automapper 这样的库可以提供帮助,但最终你必须自己做。

另一个问题是您是否真的想使用 db4o UUID 来识别对象。db4o UUID 很大,不是众所周知的类型。我个人更喜欢常规的 .NET GUID。

顺便说一句:有 db4o .Bind() 方法,它将一个对象绑定到一个现有的 id。然而,它几乎没有你真正想要的。我猜您想存储对对象所做的更改。Bind 基本上替换了对象并破坏了对象图。例如,如果你有一个部分加载的对象然后绑定它,你就会失去对对象的引用。所以 .Bind 不可用。

于 2011-05-02T08:06:00.123 回答
1

好的,Gamlor 对 db4o IExtContainer.Bind() 方法的回应为我指明了解决方案。请注意,此解决方案仅在对数据库的访问受到严格控制且没有外部查询可以检索对象实例的特定情况下有效。

警告:此解决方案很危险。它可以用各种重复和垃圾对象填充您的数据库,因为它会替换对象并且不会更新其值,因此会破坏对它的任何引用。单击此处获取完整说明

更新:即使在严格控制的情况下,这也可能会导致无休止的头痛(就像我现在遇到的那样),而不是仅具有值类型属性(字符串、int 等)的平面对象。除非您可以设计代码以在单个 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);
}
于 2011-05-03T09:10:10.670 回答