这就是我正在考虑使用DB4o的方式。当我需要查询时,我将打开文件,阅读并关闭:

using (IObjectContainer db = Db4oFactory.OpenFile(Db4oFactory.NewConfiguration(), YapFileName))
{
    try
    {
        List<Pilot> pilots = db.Query<Pilot>().ToList<Pilot>();
    }
    finally
    {
       try { db.Close(); }
       catch (Exception) { };
    }
}

稍后,当我需要插入时,
using (IObjectContainer db = Db4oFactory.OpenFile(Db4oFactory.NewConfiguration(), YapFileName))
{
    try
    {
        Pilot pilot1 = new Pilot("Michael Schumacher", 100);
        db.Store(pilot1);
    }
    finally
    {
       try { db.Close(); }
       catch (Exception) { };
    }
}

这样,我想我将通过仅在需要时打开它并在大多数时间关闭它来保持文件整洁。但是我不断收到InvalidCastException
Unable to cast object of type 'Db4objects.Db4o.Reflect.Generic.GenericObject' to type 'Pilot'

使用DB4o的正确方法是什么?

最佳答案

不,以这种方式工作不是一个好主意。 db4o ObjectContainers旨在始终在您的应用程序运行时保持打开状态。有两个原因:

  • db4o维护用于标识持久对象的参考系统,因此当您对已存储的对象(而不是存储新对象)调用#store()时,它可以进行更新。当您关闭ObjectContainer时,此参考系统将关闭,因此更新将无法进行。
  • 每次重新打开数据库文件时,都必须从数据库文件中读取
  • 类元数据。使用db4o时,还必须再次分析所有持久性类的结构。尽管这两种操作都非常快,但是您可能不想每次存储一个对象时都产生这种开销。
  • db4o具有用于类和字段索引以及数据库文件本身的非常高效的高速缓存。如果关闭并重新打开文件,则不会利用它们。
  • 您设置代码的方式在使用多个线程时可能会失败。如果两个线程想要完全同时打开数据库文件怎么办? db4o数据库文件只能打开一次。可以对同一个打开的实例运行多个事务和多个线程,如果需要多个事务,也可以使用客户端/服务器模式。
  • 稍后您可能想尝试透明激活和透明持久性。透明激活在第一次访问对象成员时会延迟加载它们。透明持久性自动存储在事务中修改的所有对象。为了使透明激活(TA)和透明持久性(TP)正常工作,您必须保持ObjectContainer打开。

  • 您无需担心会不断拥有一个打开的数据库文件。 db4o的主要目标之一是在(移动)设备中的嵌入式使用。这就是为什么我们以这样的方式编写db4o的原因:即使文件仍处于打开状态,您也可以随时关闭计算机而不会冒数据库损坏的风险。

    为什么要取回GenericObject而不是Pilot对象的可能原因:
  • 当包含Pilot对象的程序集的程序集名称在两次运行之间更改时,可能会发生这种情况,这是因为您使VisualStudio自动生成了该名称,或者是因为您手动更改了它。
  • 也许“db4o”是您的程序集名称的一部分?最近的构建之一在过滤内部类方面过于激进。这个问题早已解决。您可能想下载并尝试最新版本,“开发”或“生产”应该都可以。
  • 在一次演示中,我曾经看到过在“using”块中打开db4o ObjectContainers时出现的怪异症状。无论如何,您可能都想不这样做而将db4o ObjectContainer始终保持打开状态。
  • 关于db4o - 是否可以打开DB4o文件进行多次查询,插入,更新?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2998794/

    10-10 02:17