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 枚举?


我已经缩小了范围,我上面的例子没有包括麻烦的部分。与枚举字段无关,但与上述表达式中的“值”有关。

具体来说,当查询包含值的 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

好吧,我没有尝试过您的代码,但对我来说,这看起来像是一个错误,可能在本机查询优化器中。第一个是典型的本机查询,应该进行优化。而且我猜这里出了点问题。第二个查询可能无法优化,因为它是一种不寻常的查询方式。在这种情况下,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中的错误发布。(也许你已经在这里注册以获得 bugtracker 的帐户,我不确定。)

于 2011-03-05T16:28:45.333 回答
0

我终于在一个孤立的项目中重现了它(在主项目中进一步缩小了范围之后)。

发生此特定错误的条件非常具体。鉴于我在问题中发布的最后一个示例代码:

  • SomeClass 是另一个类的子类。字段在基类中定义
  • 示例代码中的 someInstance,必须是同一个基类的子类
于 2011-03-05T19:05:16.457 回答