可以打开DB4o文件进行多次查询,插入,更新吗?

Kev*_*nle 2 db4o

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

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

稍后,当我需要插入时,那么

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) { };
    }
}
Run Code Online (Sandbox Code Playgroud)

通过这种方式,我认为只要在需要时将文件打开,我就会保持文件更整洁,并且大部分时间都关闭它.但我一直得到InvalidCastException

Unable to cast object of type 'Db4objects.Db4o.Reflect.Generic.GenericObject' to type 'Pilot'
Run Code Online (Sandbox Code Playgroud)

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

Car*_*ger 5

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

  • db4o维护一个引用系统来标识持久对象,因此它可以在已经存储的对象(而不是存储新对象)上调用#store()时进行更新.关闭Ob​​jectContainer时,此引用系统将关闭,因此更新将不起作用.
  • 每次重新打开时,都必须从数据库文件中读取类元数据.db4o还必须在使用它们时再次分析所有持久化类的结构.虽然这两个操作都非常快,但每次存储单个对象时,您可能不希望这种开销.
  • db4o具有非常高效的类和字段索引以及数据库文件本身的缓存.如果您关闭并重新打开该文件,则不会利用它们.
  • 当您使用多个线程时,您设置代码的方式可能会失败.如果两个线程想要在同一时间打开数据库文件怎么办?db4o数据库文件只能打开一次.可以针对同一个打开的实例运行多个事务和多个线程,如果需要多个事务,也可以使用客户端/服务器模式.
  • 稍后您可能想尝试透明激活和透明持久性.首次访问时,透明激活会懒惰地加载对象成员.透明持久性自动存储在事务中修改的所有对象.要使透明激活(TA)和透明持久性(TP)工作,您必须保持ObjectContainer打开.

您不必担心持续打开数据库文件.db4o的关键目标之一是(移动)设备中的嵌入式使用.这就是为什么我们以这样的方式编写db4o,即使文件仍处于打开状态,您也可以随时关闭计算机而不会有数据库损坏的风险.

您获得GenericObject而不是Pilot对象的可能原因:

  • 当包含Pilot对象的程序集的程序集名称在两次运行之间发生更改时,可能会发生这种情况,原因是您让VisualStudio自动生成名称或者您手动更改了名称.
  • 也许"db4o"是你的程序集名称的一部分?最近的一个版本在过滤内部类时过于激进.这已在很久以前得到修复.您可能希望下载并尝试最新版本,"开发"或"生产"都应该没问题.
  • 在曾经做过的演示中,当我在"使用"块中打开db4o ObjectContainers时,我曾经看到过非常奇怪的症状.无论如何,您可能希望无需工作,并始终保持db4o ObjectContainer的打开状态.