Linq Projection在NHibernate 3.2中被错误地缓存

Gre*_*rts 6 .net c# linq nhibernate

给定如下的简单投影,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();
Run Code Online (Sandbox Code Playgroud)

预期

result1值为Name ="Bob",BadArg = 1

result2值为Name ="Bob",BadArg = 2

实际

result1值为Name ="Bob",BadArg = 1

result2值为Name ="Bob",BadArg = 1

显然,如果你不期待它,这会导致许多疯狂的行为.我在NHibernate的bug跟踪中看到过类似的错误报告,但自去年五月以来一直没有采取任何行动.因此,要么没有人使用Linq来进行Nhibernate,要么有一些我不知道的解决方法.

在深入了解NHibernate源代码之前,是否有办法禁用查询计划缓存以防止此行为或其他一些变通方法,或者是否有人应用上述链接中的补丁?

注意

这个例子是为了让问题保持简单,实际上我有一个复杂的投影,我想保留为IQueryable,过早转换为IEnumerable将无法正常工作.

更新 在Nhibernate 3.2.1的github master中不起作用

Ryt*_*mis 0

如果您想完全避免缓存,请尝试将代码更改为:

int argValue = 1;
var result1 = database.Users.AsEnumerable().Select(x => new {x.Name, BadArg = argValue}).First();

argValue = 2;
var result2 = database.Users.AsEnumerable().Select(x => new {x.Name, BadArg = argValue}).First();
Run Code Online (Sandbox Code Playgroud)

所发生的情况是,您最终将使用 System.Linq Select 方法,而不是使用 NHLinq Select 方法——有效地阻止 NHibernate 缓存投影。当然,缺点是您将在内存中进行投影,因此您最终会从用户表中选择所有字段,而不仅仅是您想要的字段。