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

C# 在一个DB4O会话中检索对象,在另一个会话中存储(';断开连接的场景';),c#,.net,db4o,object-oriented-database,oodb,C#,.net,Db4o,Object Oriented Database,Oodb,我试图弄清楚如何在DB4O中的客户端会话之间保持对象可用。据我所知,一旦客户端会话关闭,该对象就不再驻留在任何缓存中,尽管我有一个有效的UUID,但如果不插入副本,我就无法对其调用Store。我搜索了一种手动将其重新添加到缓存的方法,但没有这种机制。重新检索它将迫使我复制现在无用对象的所有值 以上代码段如下: Person person = new Person() { FirstName = "Howdoyu", LastName = "Du" }; Db4oUUID uuid; // S

我试图弄清楚如何在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]属性或通过存储(uid,object)支持这些场景


有什么想法吗?

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

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

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


顺便说一下:这里有db4o.Bind()方法,该方法将对象绑定到现有id。但是它几乎不能满足您的实际需要。我猜您希望存储对对象所做的更改。Bind基本上会替换对象并破坏对象图。例如,如果您有一个部分加载的对象,然后将其绑定,则会丢失对对象的引用。因此。Bind不可用。

好的,Gamlor关于db4o IExtContainer.Bind()方法的回答为我指明了解决方案。请注意,此解决方案仅在对DB的访问受到严格控制的非常特定的情况下有效,并且外部查询无法检索对象实例

警告:此解决方案非常危险。它可以用各种重复对象和垃圾对象填充数据库,因为它会替换对象,并且不会更新其值,因此会破坏对它的任何引用

更新:即使在严格控制的情况下,这也会导致除仅具有值类型属性(字符串、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);
}

感谢您的回复,我并没有真正期待一个解决方案:(的确,GUI更易于使用,我原本希望使用它们,但我认为如果确实存在一个解决方案,它很可能会使用UUID。我现在不得不在替代的、不太成熟的OODB和(非常遗憾的)OODB之间进行选择)回到ORM.Bind()的肥臂事实上,在我的特定场景中是可以使用的,我完全控制数据访问,除了我自己,没有任何外部查询可以检索对象实例。我在这里发布了一个答案。我只想说bind替换了对象,而不更新它。这在复杂的对象图中尤其危险,因为它会产生不一致的但是如果它对你有效,那么它很好。对,这就是为什么我在大警告中加上:)我只想补充一点,检索不需要由UUID完成。只要在检索inactiveReference之前在客户端上将ActivateDepth设置为0,任何其他字段都可以工作。