I have problem with the NHibernate’s second level cache. When I use query:
var items1 = Session.Query<Row>()
.Cacheable();
.Fetch(x => x.Field)
.OrderBy(x => x.Field.Value)
.ToList();
Everything is fine – the query is cached. But when I want to use Dynamic Linq (a link):
var items2 = Session.Query<Row>()
.Cacheable();
.Fetch(x => x.Field)
.OrderBy("Field.Value")
.ToList();
The query is not cached. Interesting thing is that, when I delete code line:
.Fetch(x => x.Field)
caching works again. So the problem is with using Fetch and dynamic linq OrderBy methods together.
EDIT:
When I try do debug NH code (QueryKey class), debugger tells me that these two queries do not have the same ResultTransformer (and deeper: a listTransformation private instance).
Any ideas?
Chris
Ok, I know what is the reason.
Dynamic Linq doesn’t use Parameter Names in Linq Expressions. E.g. if I want to sort using lambda statemant, I write:
Above we see an
itemlambda parameter name.When I use Dynamic linq:
in the result Queryable the lambda parameter in OrderBy mehod has no name (like
itemwritten above). We can illustrate the result like this:And now, when NHibernate is decoding that Queryable expression and finds there an expression parameter that has no name, NH gives it a random name using GUID class. So every ordering using dynamic linq produces a Queryable Expression that has inconstant lambda parameter. This is the reason why NHibernate thinks that:
query.OrderBy("Name")andquery.OrderBy("Name")are not the same – they have another lamda parameters generated every time from scratch.SOLUTION
If you want to fix it, you have to modify Dynamic Linq library.
In method
ExpressionParser.ProcessParameterschange line:to:
In method
DynamicQueryable.OrderBychange line:to:
Now,
query.OrderBy("Name")will producequery.OrderBy(it => it.Name).Cheers!