检索一个db40会话中的对象,存储在另一个会话中('断开连接的场景')

本文关键字:会话 断开 连接 另一个 对象 一个 db40 检索 存储 | 更新日期: 2023-09-27 17:53:57

我试图弄清楚如何在db40的客户端会话之间保持对象可用。据我所知,一旦客户端会话关闭,对象就不再驻留在任何缓存中,尽管我有一个有效的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)。

任何想法吗?

检索一个db40会话中的对象,存储在另一个会话中('断开连接的场景')

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

你基本上必须通过复制所有属性来编写自己的reattach方法。也许Automapper这样的库能帮上忙,但最终你还是得自己动手。

另一个问题是,您是否真的想使用db40uuid来标识对象。db40 uuid非常大,不是一种众所周知的类型。我个人更喜欢常规的。net guid。

顺便说一下:有db40 . bind()方法,它将对象绑定到现有的id。然而,它很难达到你真正想要的效果。我猜您希望存储对对象所做的更改。Bind基本上是替换对象并破坏对象图。例如,如果您有一个部分加载的对象,然后将其绑定,则会丢失对对象的引用。所以。bind是不可用的。

好吧,Gamlor对db40iextcontainer . bind()方法的响应为我指出了解决方案。请注意,此解决方案仅在对DB的访问受到严格控制的非常特殊的情况下有效,并且没有外部查询可以检索对象实例。

警告:此解决方案是危险的。它可以用各种重复对象和垃圾对象填充数据库,因为它替换对象而不更新其值,从而破坏对它的任何引用。点击这里查看完整的解释。

UPDATE:即使在严格控制的场景中,对于除了只有值类型属性(string, int等)的平面对象之外的任何对象,这也会导致无尽的头痛(就像我现在遇到的问题)。除非您可以将代码设计为在单个db40连接中检索、编辑和保存对象,否则我建议根本不要使用db40。

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