C# 在一个DB4O会话中检索对象,在另一个会话中存储(';断开连接的场景';)
我试图弄清楚如何在DB4O中的客户端会话之间保持对象可用。据我所知,一旦客户端会话关闭,该对象就不再驻留在任何缓存中,尽管我有一个有效的UUID,但如果不插入副本,我就无法对其调用Store。我搜索了一种手动将其重新添加到缓存的方法,但没有这种机制。重新检索它将迫使我复制现在无用对象的所有值 以上代码段如下: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
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,任何其他字段都可以工作。