哪些特定条件可能会导致 db4o 的本机查询转换错误?
这会失败:
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);
This fails:
var results = container.Query<SomeClass>(s =>
s.Field == value && s.AnEnumField != SomeEnum.AnEnumValue
);
Assert.AreEqual(1, results.Count);
But this doesn't:
Predicate<SomeClass> matches = s =>
s.Field == value && s.AnEnumField != SomeEnum.AnEnumValue;
var results = container.Query<SomeClass>(s => matches(s));
Assert.AreEqual(1, results.Count);
The different in the tests clearly demonstrates the issue happens only when db4o does the expression transformation, as calling a method prevents that. The value checked in the test, is the exact value (no case differences), as the test inserts it first.
Any special conditions where the db4o transformations has bugs with those queries? maybe with .net enums?
I have narrowed it down, and my example above didn't include the troublesome bit. Doesn't have to do with the enum field, but with "value" in the above expression.
Specifically the issue happens when the query includes someInstance.Field for the value, like:
var results =
container.Query<SomeClass>(s =>
s.Field == someInstance.Field && s.AnEnumField != SomeEnum.AnEnumValue
);
Assert.AreEqual(1, results.Count);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
好吧,我没有尝试你的代码,但对我来说,这看起来像是一个错误,可能在本机查询优化器中。第一个是典型的本机查询,应该进行优化。我猜肯定是出了什么问题。
第二个查询可能无法优化,因为这是一种不寻常的查询编写方式。在这种情况下,db4o 仅调用闭包/委托,因此会产生正确的结果。
要解决此错误,我建议您使用 LINQ。在项目中包含“Db4objects.Db4o.Linq.dll”程序集,添加“Db4objects.Db4o.Linq”命名空间并编写查询。例如这样:
无论如何,我建议您使用 LINQ 而不是本机查询。 LINQ 更强大并且是一个“标准”API。
对于原始问题:也许将其作为一个小示例程序作为 db4o-bugtracker 中的错误发布。 (也许您已在此处注册以获得 bugtracker 的帐户,我不确定关于那件事。)
Well I didn't tried out your code, but to me that looks like a bug, probably in the native-query optimizer. The first one it a typical native query which should be optimization. And I guess that there something goes wrong.
The second query probably cannot be optimized, because is a unusual way to write a query. In that case db4o just calls the closure/delegate and therefore produces the right result.
To work around this bug I would recommend you to use LINQ. Include the 'Db4objects.Db4o.Linq.dll'-assembly in your project, add the 'Db4objects.Db4o.Linq'-namespace and write the queries. For example like this:
I would recommend you anyway to use LINQ instead of native queries. LINQ is much more powerful and a 'standard'-API.
For the original issue: Maybe post this as a small example program as an bug in the db4o-bugtracker. (Maybe you have register here to get an account for the bugtracker, I'm not sure about that.)
我终于在一个独立的项目中重现了它(在主项目中进一步缩小范围之后)。
发生此特定错误的条件非常具体。鉴于我在问题中发布的最后一个示例代码:
I finally got to reproduce it in an isolated project (after narrowing it down more in the main project).
Conditions under which this particular bug occur are very specific. Given the last sample code I posted in the question: