0

これは失敗します:

var results = container.Query<SomeClass>(s =>
    s.Field == value && s.AnEnumField != SomeEnum.AnEnumValue
);
Assert.AreEqual(1, results.Count);

しかし、これはしません:

Predicate<SomeClass> matches = s => 
    s.Field == value && s.AnEnumField != SomeEnum.AnEnumValue;
var results = container.Query<SomeClass>(s => matches(s));
Assert.AreEqual(1, results.Count);

テストの違いは、メソッドを呼び出すことでそれが妨げられるため、db4oが式の変換を行う場合にのみ問題が発生することを明確に示しています。テストでチェックされる値は、テストが最初に挿入するため、正確な値(大文字と小文字の違いはありません)です。

db4oトランスフォーメーションにこれらのクエリにバグがある特別な条件はありますか?多分.net列挙型で?


私はそれを絞り込みました、そして上記の私の例は厄介なビットを含んでいませんでした。enumフィールドとは関係ありませんが、上記の式の「value」と関係があります。

具体的には、クエリに次のような値のsomeInstance.Fieldが含まれている場合に問題が発生します。

var results =
container.Query<SomeClass>(s =>
   s.Field == someInstance.Field && s.AnEnumField != SomeEnum.AnEnumValue
); 
Assert.AreEqual(1, results.Count);
4

2 に答える 2

2

私はあなたのコードを試していませんでしたが、おそらくネイティブクエリオプティマイザのバグのように見えます。最初のものは、最適化されるべき典型的なネイティブクエリです。そして、何かがうまくいかないと思います。2番目のクエリは、クエリを作成するための通常とは異なる方法であるため、おそらく最適化できません。その場合、db4oはクロージャ/デリゲートを呼び出すだけなので、正しい結果が得られます。

このバグを回避するには、LINQを使用することをお勧めします。プロジェクトに「Db4objects.Db4o.Linq.dll」アセンブリを含め、「Db4objects.Db4o.Linq」名前空間を追加してクエリを記述します。たとえば、次のようになります。

var result = from SomeClass s in container
               where s.Field == value && s.AnEnumField != SomeEnum.AnEnumValue
               select s;
Assert.AreEqual(1, results.Count);

とにかく、ネイティブクエリの代わりにLINQを使用することをお勧めします。LINQははるかに強力で、「標準」のAPIです。

元の問題の場合: db4o-bugtrackerのバグとして、これを小さなサンプルプログラムとして投稿してください。(バグトラッカーのアカウントを取得するためにここに登録しているかもしれませんが、それについてはよくわかりません。)

于 2011-03-05T16:28:45.333 に答える
0

私はついにそれを孤立したプロジェクトで再現するようになりました(メインプロジェクトでさらに絞り込んだ後)。

この特定のバグが発生する条件は非常に具体的です。私が質問に投稿した最後のサンプルコードを考えると:

  • SomeClassは、別のクラスのサブクラスです。フィールドは基本クラスで定義されます
  • サンプルコードのsomeInstanceは、同じ基本クラスのサブクラスである必要があります
于 2011-03-05T19:05:16.457 に答える