2

これが私が考えている 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 を使用する正しい方法は何ですか?

4

2 に答える 2

5

いいえ、この方法で作業するのは得策ではありません。db4o ObjectContainers は、アプリケーションの実行中常に開いたままにすることを目的としています。いくつかの理由:

  • db4o は、永続オブジェクトを識別するための参照システムを維持しているため、(新しいオブジェクトを格納する代わりに) 既に格納されているオブジェクトに対して #store() を呼び出すと、更新を行うことができます。この参照システムは、ObjectContainer を閉じると閉じられるため、更新は機能しません。
  • クラス メタデータは、データベース ファイルを再度開くたびに読み取る必要があります。また、db4o は、使用時にすべての永続クラスの構造を再度分析する必要があります。どちらの操作も非常に高速ですが、単一のオブジェクトを保存するたびにこのオーバーヘッドが発生することは望ましくありません。
  • db4o には、クラスとフィールドのインデックス、およびデータベース ファイル自体のための非常に効率的なキャッシュがあります。ファイルを閉じて再度開いても、それらを利用することはできません。
  • コードを設定した方法では、複数のスレッドを操作するときにエラーが発生する可能性があります。2 つのスレッドがまったく同時にデータベース ファイルを開こうとするとどうなるでしょうか。db4o データベース ファイルは一度だけ開くことができます。同じオープン インスタンスに対して複数のトランザクションと複数のスレッドを実行することが可能であり、複数のトランザクションが必要な場合はクライアント/サーバー モードを使用することもできます。
  • 後で、Transparent Activation と Transparent Persistence を試すことができます。透過的なアクティブ化は、オブジェクト メンバーが最初にアクセスされたときに遅延ロードします。透過的な永続性は、トランザクションで変更されたすべてのオブジェクトを自動的に保存します。透過的アクティベーション (TA) と透過的持続性 (TP) が機能するには、ObjectContainer を開いたままにしておく必要があります。

データベース ファイルを常に開いておく必要はありません。db4o の主なターゲットの 1 つは、(モバイル) デバイスでの組み込み使用です。そのため、ファイルがまだ開いている場合でも、データベースが破損する危険を冒さずに、いつでもマシンの電源を切ることができるように db4o を作成しました。

Pilot オブジェクトではなく GenericObject が返される理由として考えられるのは、次のとおりです。

  • これは、Pilot オブジェクトを含むアセンブリのアセンブリ名が 2 回の実行の間に変更された場合に発生する可能性があります。これは、VisualStudio に名前を自動生成させたか、手動で変更したためです。
  • 「db4o」がアセンブリ名の一部ではないでしょうか。最近のビルドの 1 つは、内部クラスのフィルター処理があまりにも積極的でした。これはかなり前に修正されています。最新のリリースをダウンロードして試してみることをお勧めします。「開発」または「本番」のどちらでも問題ありません。
  • 以前のプレゼンテーションで、db4o ObjectContainers が「using」ブロックで開かれたときに、非常に奇妙な症状が見られました。とにかくそれなしで作業し、db4o ObjectContainer を常に開いたままにしておくことをお勧めします。
于 2010-06-08T20:57:33.070 に答える
1

データベースを複数回再度開くことは問題ありません。問題は、パフォーマンスと「アイデンティティ」の喪失です。また、クエリの結果への参照を保持し、データベースを閉じた後にそれを反復しようとすることはできません(コードに基づいて、あなたがそれをしたいように見えます)。

GenericObjectsは、クラスが見つからない場合にインスタンス化されます。

失敗する完全でミニマリストなサンプルを提供できますか?

また、どのdb4oバージョンを使用していますか?

一番

于 2010-06-08T15:44:25.250 に答える