C# 奇怪的 lambda 行为
有人可以指出为什么会发生这种情况:
我正在使用 NHibernate
和 Linq
提供程序。
失败的代码列于此处:
var sequence = session.Query<T>();
var wtfSequence = sequence.Where(x => true);
var okaySequence = sequence.Where(x => x.Id > 0);
调试显示此后的 sequence
(这是一个 IQueryable
)包含 2 个元素,分别是添加到数据库中。
我希望第一个 Where
语句生成该序列中的所有元素,但不幸的是它留下了 0 个元素。
(为什么??? )
相反,第二个 Where
语句实际上会产生 2 个元素,因为它应该起作用。
这里是NHibernate -> Sqlite
查询第一个和第二个 Where
语句。
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
时会发生这种情况?这是一个错误还是我做错了什么?
谢谢。
Could someone point out why this could be happening:
I am using NHibernate
and the Linq
provider for it.
The code that fails is listed here:
var sequence = session.Query<T>();
var wtfSequence = sequence.Where(x => true);
var okaySequence = sequence.Where(x => x.Id > 0);
Debugging shows that sequence
(which is an IQueryable<T>
) after this contains 2 elements, which were added to the database.
I expect the first Where
statement to yield all elements from that sequence, but unfortunately it leaves 0 elements.
(WHY???)
The second Where
statement, on the contrary, actually yields 2 elements as it should work.
Here are the NHibernate -> Sqlite
queries for the first and second Where
statements.
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)]
Now, if I test the same code with my InMemoryRepository
, which stores every entity in a simple list, the (x => true)
works absolutelty fine.
So - why does this happen when using NHibernate
? Is this a bug or I am doing something wrong?
Thank you.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我不了解 NHibernate,但从生成的 SQL 中问题很明显:您的数据库不认为 true(小写 t)等于 True(大写 T)。在 SQL Server 中,您可以通过修改数据库排序规则来更改此设置(这是一个非常糟糕的主意,除非您出于其他原因希望不区分大小写)。
我的猜测是这是 NHibernate 中的一个错误,您需要解决它。测试
t => 1 == 1
而不是t => true
,这可能会起作用,具体取决于 NHibernate 代码的编写方式。I don't know NHibernate, but the problem is obvious from the generated SQL: Your database does not consider true (lowercase t) equal to True (uppercase T). In SQL server you can change this by modifying the database collation (which is a really bad idea unless you want case insensitivity for other reasons).
My guess is this is a bug in NHibernate that you need to work around. Test
t => 1 == 1
instead oft => true
, which might work depending on how the NHibernate code is written.我的猜测是,根据您显示的 SqLite 输出,这是 NHibernate 中的一个错误。您可以尝试
X => X.Id == X.Id
而不是X => true
并看看是否有效。My guess is that this is a bug in NHibernate based on the SqLite output that you show. You could try
X => X.Id == X.Id
rather thanX => true
and see if that works.对我来说看起来像一个错误。它将布尔运算转换为字符串计算,甚至搞砸了,因为它使用
true
设置查询并使用True
进行计算,因此区分大小写的测试将失败。Looks like a bug to me. Its converting a boolean operation to a string evaluation, and even that's screwed up, as it sets up the query with
true
and evaluates usingTrue
, so a case-sensitive test would fail.