繁体   English   中英

意外的Linq行为-ToList()

[英]Unexpected Linq Behavior - ToList()

从理论上讲,我有两个类似的查询返回相同的结果:

var requestNotWorking = SessionManagement.Db.Linq<Item>(false).Where(i => 
                        i.Group != null && i.Group.Id == methodParameter)
                       .ToList();

即使该请求应该返回一个,该请求也返回0个项目。 以下是后者的重写,但是调用了ToList()方法。 此请求有效并返回第一个查询中期望的项目!

var requestWorking = SessionManagement.Db.Linq<Item>(false).ToList().Where(i => 
                     i.Group != null && i.Group.Id == methodParameter).ToList();

注意: SessionManagement.Db.Linq<Item>(false)是通用的Linq to Nhibernate方法,具有boolean属性,该属性确定是否必须在缓存(true)或数据库(false)中执行请求。 该方法没有问题,因为它在解决方案的许多其他部分都可以正常工作。 Item的映射没什么花哨的:没有包装袋和以下参数: lazy="false" schema="dbo" mutable="false" polymorphism="explicit"

为什么会这样呢?

编辑

生成的requestNoWorking的sql请求以结尾:

(Item.Group_ID is not null) and Item.Group_ID=@p0',N'@p0 int',@p0=11768

生成的requestWorking的sql请求大致是dbo.Items中的select * from dbo.Items

我假设您在那里进行的nhibernate会话返回一个可查询的对象。 如果是这样,则对第一个查询的评估将延迟到.ToList()调用之后,并且整个查询将在服务器上运行。 我建议您尽可能在sql服务器上运行跟踪,或者下载NHProf以查看正在执行的实际查询是什么。

当您点击第一个.ToList() ,便会评估第二个查询,因此您要从数据库中拉回整个表,然后使用.net进行过滤。 老实说,我无法告诉您他们为什么会做出不同的评估,但是我认为映射/配置中存在某些问题,导致db查询被编写为略有错误。

我对您对c.Group.Id != null理论非常感兴趣,尽管与我的解决方案中的其他代码相矛盾,但我认为这很合逻辑。 但是,删除它并没有改变任何东西。 我发现删除mutable="false"属性可以解决此问题。 似乎有些神奇,但它确实有效。

我发布的请求实际上是在检查更新/删除可能性的方法中发生的。 我的结论是,以某种方式使Item变为不可变会破坏结果。 但是我不明白的是为什么requestWorking如此有效!

我所看到的是在第二版中,您的Where是由LINQ to Objects而不是LINQ to NHibernate执行的。 因此,第一个版本必须做的事情是LINQ to NHibernate不能很好地消化。

这是LINQ To NHibernate遇到的问题i.Group != null ,因为看到null的使用是CLR特定的。 您可能需要在LINQ to NHibernate中使用其他构造来测试空字段值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM