Linq Projection caches incorrectly in NHibernate 3.2

Given a simple projection like the following, NHibernate will cache the query plan and not update the value of the variable when the query is the same:

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(); 

Expected

The value of result1 will be Name = "Bob" and BadArg = 1

The value of result2 will be Name = "Bob" and BadArg = 2

Actual

The value of result1 will be Name = "Bob" and BadArg = 1

The value of result2 will be Name = "Bob" and BadArg = 1

Obviously, this can cause a lot of crazy things if you do not expect this. I saw a bug report similar to this in NHibernate bug tracking, but no action has been taken since last May. Thus, either no one uses Linq for Nhibernate very much or there is some workaround that I do not know about.

Before I go to the NHibernate source, is there a way to disable query plan caching to prevent this behavior or some other workaround, or did anyone apply the patch from the above link?

Note

This example is intended to provide a simple answer to the question: in fact, I have a complex projection that I want to save as IQueryable, a premature conversion to IEnumerable will not work.

Update Doesn't work in github master for Nhibernate 3.2.1

+6
source share
2 answers

If you want to completely exclude caching, try changing your code to this:

 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(); 

What happens is that instead of using the NHLinq Select method, you end up using the System.Linq Select method - effectively preventing NHibernate projection caching. Of course, the disadvantage is that you do the projection in memory, so in the end you will select all the fields from the table of your users, and not just the ones you want.

0
source

Here's how to disable the first level cache: http://darioquintana.com.ar/blogging/2007/10/08/statelesssession-nhibernate-without-first-level-cache/

I don’t think you can disable the second level cache, but I think you don’t need this problem.

(Essentially, you will need to create and destroy sessions for each request.)

If you find that the problem is still persisting, you will have to do what Rhythmis suggested.

0
source

Source: https://habr.com/ru/post/905260/


All Articles