So, I have a query like
public static IEnumerable<Archive> GetArchivesRecursive(this ISession session, Page rootPage)
{
var archives = session.Query<Page>().Where(p => p != rootPage && p.Path.StartsWith(rootPage.Path))
.GroupBy(p => new { Year = p.Published.Year, Month = p.Published.Month })
.Select(g => new Archive
{
ContextPageId = rootPage.Id,
Year = g.Key.Year,
Month = g.Key.Month,
TotalPageCount = g.Count(),
PublicPageCount = g.Count(p => p.State == PageState.Public && p.Published <= DateTime.UtcNow)
})
.ToList();
// ContextPageId has old value (id of the first rootPage used since app start)
// Why do I have to do this?
archives.ForEach(a => a.ContextPageId = rootPage.Id);
return archives;
}
For some reason ContextPageId property gets value of the first rootPage parameter that was used.
Well, quite interesting, my NH 3.2 actually fails with
MismatchedTreeNodeExceptionfor even simplier queries when trying to have value from input inSelectinside query. Which version are you using?Anyway, looks like you just can’t use values from outside the query in projection (
Select) and this is probably NHibernate’s Linq limitation. Your version seems to cache the compiled expression fromSelectignoring the fact that it depends from a variable.DateTimevalue is the same for all calls, too, isn’t it?A bit cleaner workaround could go like this:
EDIT I’ve looked a bit more carefully and this indeed is a NHibernate bug, already known. See this blog post and this JIRA bug entry.