问题描述
|
我试图弄清楚如何使对象在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)支持这些情况。
有什么想法吗?
解决方法
db4o =(。)中确实缺少此功能。这使得db4o在许多情况下很难使用。
基本上,您必须通过处理所有属性来编写自己的重新连接方法。也许像Automapper这样的库可以提供帮助,但是最后您必须自己做。
另一个问题是您是否真的要使用db4o UUID来标识对象。 db4o UUID很大,并且不是众所周知的类型。我个人更喜欢常规的.NET GUID。
顺便说一句:有db4o .Bind()方法,该方法将对象绑定到现有ID。但是,它几乎没有您真正想要的。我猜您想存储对对象所做的更改。绑定基本上会替换对象并破坏对象图。例如,如果您有一个部分加载的对象然后绑定了它,则您将丢失对对象的引用。因此,.Bind不可用。
,好的,Gamlor对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);
}