C#奇怪的lambda行为

8

有人能指出为什么会发生这种情况吗:

我正在使用 NHibernate 和其 Linq 提供程序。

以下是失败的代码:

var sequence = session.Query<T>();

var wtfSequence = sequence.Where(x => true);
var okaySequence = sequence.Where(x => x.Id > 0);

调试显示,此后sequence(它是一个IQueryable<T>)包含2个元素,这些元素已添加到数据库中。

我期望第一个Where语句从该序列中产生所有元素,但不幸的是它没有产生任何元素。

(为什么???)

相反,第二个Where语句实际上产生了应该工作的2个元素。

这里是第一个和第二个Where语句的NHibernate -> Sqlite查询。

NHibernate: select cast(count(*) as INTEGER) as col_0_0_ from "BinaryUnitProxy_IndicatorUnitDescriptor" binaryunit0_ where @p0='true';@p0 = 'True' [Type: String (0)]

NHibernate: select cast(count(*) as INTEGER) as col_0_0_ from "BinaryUnitProxy_IndicatorUnitDescriptor" binaryunit0_ where binaryunit0_.Id>@p0;@p0 = 0 [Type: Int32 (0)]

现在,如果我使用我的InMemoryRepository测试相同的代码,它会将每个实体存储在一个简单的列表中,并且(x => true)完全正常工作。

那么,为什么使用NHibernate时会出现这种情况?这是一个错误还是我做错了什么?

谢谢。


2
很可能与NHibernate处理从lambda创建的表达式的方式有关,尽管谁知道它在做什么... - Massif
3个回答

5
我不熟悉NHibernate,但从生成的SQL语句中可以看出问题很明显:您的数据库认为true(小写t)与True(大写T)不相等。在SQL Server中,您可以通过修改数据库排序规则来解决此问题(除非您有其他原因需要区分大小写,否则这是一个非常不好的想法)。
我猜测这可能是NHibernate中的一个bug,您需要解决它。尝试使用t => 1 == 1代替t => true进行测试,具体取决于NHibernate代码的编写方式。

2
我的猜测是这是NHibernate的一个bug,基于你展示的SqLite输出。你可以尝试使用 X => X.Id == X.Id 而不是 X => true,看看是否有效。

1

看起来对我来说是个错误。它将布尔运算转换为字符串评估,而且即便如此也出错了,因为它用true设置查询并使用True进行评估,所以区分大小写的测试会失败。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接