какие конкретные условия могут вызвать ошибку преобразования собственного запроса db4o? - PullRequest
0 голосов
/ 05 марта 2011

Не удалось:

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 enums?


Я сузил это, и мой пример выше не включал неприятную часть. Не относится к полю enum, но к значению в приведенном выше выражении.

В частности, проблема возникает, когда запрос включает в себя значение someInstance.Field, например:

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

Ответы [ 2 ]

2 голосов
/ 05 марта 2011

Я не пробовал ваш код, но для меня это похоже на ошибку, возможно, в оптимизаторе встроенных запросов. Первый - это типичный нативный запрос, который должен быть оптимизацией. И я думаю, что там что-то идет не так. Второй запрос, вероятно, не может быть оптимизирован, потому что это необычный способ написания запроса. В этом случае 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 . (Возможно, у вас есть регистрация здесь , чтобы получить учетную запись для багтрекера, я не уверен в этом.)

0 голосов
/ 05 марта 2011

Я наконец-то получил возможность воспроизвести его в изолированном проекте (после более узкого сужения в основном проекте).

Условия, при которых возникает данная ошибка, очень специфичны.Учитывая последний пример кода, который я разместил в вопросе:

  • SomeClass является подклассом другого класса.Поле определено в базовом классе
  • someInstance в примере кода, должно быть подклассом того же базового класса
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...