【发布时间】:2012-01-05 22:59:41
【问题描述】:
给定一个像下面这样的简单投影,NHibernate 将缓存查询计划,当查询相同时不更新变量的值:
int argValue = 1;
var result1 = database.Users.Select(x => new {x.Name, BadArg = argValue}).First();
argValue = 2;
var result2 = database.Users.Select(x => new {x.Name, BadArg = argValue}).First();
预期
result1 值为 Name = "Bob" 和 BadArg = 1
result2 值为 Name = "Bob" 和 BadArg = 2
实际
result1 值为 Name = "Bob" 和 BadArg = 1
result2 值将是 Name = "Bob" 和 BadArg = 1
如果您没有预料到,这显然会导致很多疯狂的行为。我在 NHibernate 的错误跟踪中看到了与此类似的 couple bug reports,但自去年 5 月以来一直没有采取任何行动。所以要么没有人经常使用 Linq to Nhibernate,要么有一些我不知道的解决方法。
在我深入研究 NHibernate 源之前,有没有办法禁用查询计划缓存以防止这种行为或其他一些解决方法,或者是否有人应用了上述链接中的补丁?
注意
该示例旨在使问题保持简单,实际上我有一个复杂的投影,我想将其保留为 IQueryable,过早转换为 IEnumerable 是行不通的。
更新 不适用于 Nhibernate 3.2.1 的 github master
【问题讨论】:
-
出于好奇,我一直在研究这个问题,看起来问题不在于 NHibernate 的缓存,而是 Linq 表达式树缓存。问题是,表达式树被简化了,变量引用被简化为一个常量表达式,之后缓存键被构造——但到那时,范围变量 ref 和常量之间的区别就不清楚了。 :-/
-
我也遇到过这个问题,太浪费时间了。每隔几个月它就会重新出现,我已经忘记了它,只是再次重新发现它。在我的例子中,我不是针对匿名对象进行投影,而是对我自己创造的对象进行评估。
标签: c# .net linq nhibernate