Cannot use alias between more than 1 level of nested queries
Description
This issue affects CreateCriteria. I haven't tried it with QueryOver.
Here is a query that demonstrates the problem:
Here's the relevant portion of the mapping, in Fluent NH:
The error thrown is: System.ArgumentNullException : Value cannot be null. Parameter name: key at System.Collections.Generic.Dictionary`2.FindEntry(TKey key) at System.Collections.Generic.Dictionary`2.TryGetValue(TKey key, ref TValue value) at NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetPropertyMapping(String entityName) in p:\nhibernate-core\src\NHibernate\Loader\Criteria\CriteriaQueryTranslator.cs: line 660 at NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetType(ICriteria subcriteria, String propertyName) in p:\nhibernate-core\src\NHibernate\Loader\Criteria\CriteriaQueryTranslator.cs: line 633 at NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetTypeUsingProjection(ICriteria subcriteria, String propertyName) in p:\nhibernate-core\src\NHibernate\Loader\Criteria\CriteriaQueryTranslator.cs: line 612 at NHibernate.Criterion.CriterionUtil.GetColumnNamesUsingPropertyName(ICriteriaQuery criteriaQuery, ICriteria criteria, String propertyName, Object value, ICriterion critertion) in p:\nhibernate-core\src\NHibernate\Criterion\CriterionUtil.cs: line 76 at NHibernate.Criterion.SimpleExpression.ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary`2 enabledFilters) in p:\nhibernate-core\src\NHibernate\Criterion\SimpleExpression.cs: line 81 at NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetWhereCondition(IDictionary`2 enabledFilters) in p:\nhibernate-core\src\NHibernate\Loader\Criteria\CriteriaQueryTranslator.cs: line 201 at NHibernate.Loader.Criteria.CriteriaJoinWalker..ctor(IOuterJoinLoadable persister, CriteriaQueryTranslator translator, ISessionFactoryImplementor factory, ICriteria criteria, String rootEntityName, IDictionary`2 enabledFilters) in p:\nhibernate-core\src\NHibernate\Loader\Criteria\CriteriaJoinWalker.cs: line 43 at NHibernate.Criterion.SubqueryExpression.ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary`2 enabledFilters) in p:\nhibernate-core\src\NHibernate\Criterion\SubqueryExpression.cs: line 60 at NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetWhereCondition(IDictionary`2 enabledFilters) in p:\nhibernate-core\src\NHibernate\Loader\Criteria\CriteriaQueryTranslator.cs: line 201 at NHibernate.Loader.Criteria.CriteriaJoinWalker..ctor(IOuterJoinLoadable persister, CriteriaQueryTranslator translator, ISessionFactoryImplementor factory, ICriteria criteria, String rootEntityName, IDictionary`2 enabledFilters) in p:\nhibernate-core\src\NHibernate\Loader\Criteria\CriteriaJoinWalker.cs: line 43 at NHibernate.Criterion.SubqueryExpression.ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary`2 enabledFilters) in p:\nhibernate-core\src\NHibernate\Criterion\SubqueryExpression.cs: line 60 at NHibernate.Criterion.SubqueryProjection.ToSqlString(ICriteria criteria, Int32 loc, ICriteriaQuery criteriaQuery, IDictionary`2 enabledFilters) in p:\nhibernate-core\src\NHibernate\Criterion\SubqueryProjection.cs: line 46 at NHibernate.Criterion.Order.ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery) in p:\nhibernate-core\src\NHibernate\Criterion\Order.cs: line 45 at NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetOrderBy() in p:\nhibernate-core\src\NHibernate\Loader\Criteria\CriteriaQueryTranslator.cs: line 220 at NHibernate.Loader.Criteria.CriteriaJoinWalker..ctor(IOuterJoinLoadable persister, CriteriaQueryTranslator translator, ISessionFactoryImplementor factory, ICriteria criteria, String rootEntityName, IDictionary`2 enabledFilters) in p:\nhibernate-core\src\NHibernate\Loader\Criteria\CriteriaJoinWalker.cs: line 58 at NHibernate.Loader.Criteria.CriteriaLoader..ctor(IOuterJoinLoadable persister, ISessionFactoryImplementor factory, CriteriaImpl rootCriteria, String rootEntityName, IDictionary`2 enabledFilters) in p:\nhibernate-core\src\NHibernate\Loader\Criteria\CriteriaLoader.cs: line 41 at NHibernate.Impl.SessionImpl.List(CriteriaImpl criteria, IList results) in p:\nhibernate-core\src\NHibernate\Impl\SessionImpl.cs: line 1938 at NHibernate.Impl.CriteriaImpl.List(IList results) in p:\nhibernate-core\src\NHibernate\Impl\CriteriaImpl.cs: line 265 at NHibernate.Impl.CriteriaImpl.List() in p:\nhibernate-core\src\NHibernate\Impl\CriteriaImpl.cs: line 276
The issue is because we are trying to use the alias "mk" which occurs 2 levels up of nested queries. Note that this should result in perfectly valid SQL.
I would also like to point out that the error thrown is very unfriendly. It would be good to throw a more descriptive error, e.g. "alias 'mk' cannot be found" as debugging this issue is painful.
This issue affects CreateCriteria. I haven't tried it with QueryOver.
Here is a query that demonstrates the problem:
Here's the relevant portion of the mapping, in Fluent NH:
The error thrown is:
System.ArgumentNullException : Value cannot be null.
Parameter name: key
at System.Collections.Generic.Dictionary`2.FindEntry(TKey key)
at System.Collections.Generic.Dictionary`2.TryGetValue(TKey key, ref TValue value)
at NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetPropertyMapping(String entityName) in p:\nhibernate-core\src\NHibernate\Loader\Criteria\CriteriaQueryTranslator.cs: line 660
at NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetType(ICriteria subcriteria, String propertyName) in p:\nhibernate-core\src\NHibernate\Loader\Criteria\CriteriaQueryTranslator.cs: line 633
at NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetTypeUsingProjection(ICriteria subcriteria, String propertyName) in p:\nhibernate-core\src\NHibernate\Loader\Criteria\CriteriaQueryTranslator.cs: line 612
at NHibernate.Criterion.CriterionUtil.GetColumnNamesUsingPropertyName(ICriteriaQuery criteriaQuery, ICriteria criteria, String propertyName, Object value, ICriterion critertion) in p:\nhibernate-core\src\NHibernate\Criterion\CriterionUtil.cs: line 76
at NHibernate.Criterion.SimpleExpression.ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary`2 enabledFilters) in p:\nhibernate-core\src\NHibernate\Criterion\SimpleExpression.cs: line 81
at NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetWhereCondition(IDictionary`2 enabledFilters) in p:\nhibernate-core\src\NHibernate\Loader\Criteria\CriteriaQueryTranslator.cs: line 201
at NHibernate.Loader.Criteria.CriteriaJoinWalker..ctor(IOuterJoinLoadable persister, CriteriaQueryTranslator translator, ISessionFactoryImplementor factory, ICriteria criteria, String rootEntityName, IDictionary`2 enabledFilters) in p:\nhibernate-core\src\NHibernate\Loader\Criteria\CriteriaJoinWalker.cs: line 43
at NHibernate.Criterion.SubqueryExpression.ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary`2 enabledFilters) in p:\nhibernate-core\src\NHibernate\Criterion\SubqueryExpression.cs: line 60
at NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetWhereCondition(IDictionary`2 enabledFilters) in p:\nhibernate-core\src\NHibernate\Loader\Criteria\CriteriaQueryTranslator.cs: line 201
at NHibernate.Loader.Criteria.CriteriaJoinWalker..ctor(IOuterJoinLoadable persister, CriteriaQueryTranslator translator, ISessionFactoryImplementor factory, ICriteria criteria, String rootEntityName, IDictionary`2 enabledFilters) in p:\nhibernate-core\src\NHibernate\Loader\Criteria\CriteriaJoinWalker.cs: line 43
at NHibernate.Criterion.SubqueryExpression.ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary`2 enabledFilters) in p:\nhibernate-core\src\NHibernate\Criterion\SubqueryExpression.cs: line 60
at NHibernate.Criterion.SubqueryProjection.ToSqlString(ICriteria criteria, Int32 loc, ICriteriaQuery criteriaQuery, IDictionary`2 enabledFilters) in p:\nhibernate-core\src\NHibernate\Criterion\SubqueryProjection.cs: line 46
at NHibernate.Criterion.Order.ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery) in p:\nhibernate-core\src\NHibernate\Criterion\Order.cs: line 45
at NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetOrderBy() in p:\nhibernate-core\src\NHibernate\Loader\Criteria\CriteriaQueryTranslator.cs: line 220
at NHibernate.Loader.Criteria.CriteriaJoinWalker..ctor(IOuterJoinLoadable persister, CriteriaQueryTranslator translator, ISessionFactoryImplementor factory, ICriteria criteria, String rootEntityName, IDictionary`2 enabledFilters) in p:\nhibernate-core\src\NHibernate\Loader\Criteria\CriteriaJoinWalker.cs: line 58
at NHibernate.Loader.Criteria.CriteriaLoader..ctor(IOuterJoinLoadable persister, ISessionFactoryImplementor factory, CriteriaImpl rootCriteria, String rootEntityName, IDictionary`2 enabledFilters) in p:\nhibernate-core\src\NHibernate\Loader\Criteria\CriteriaLoader.cs: line 41
at NHibernate.Impl.SessionImpl.List(CriteriaImpl criteria, IList results) in p:\nhibernate-core\src\NHibernate\Impl\SessionImpl.cs: line 1938
at NHibernate.Impl.CriteriaImpl.List(IList results) in p:\nhibernate-core\src\NHibernate\Impl\CriteriaImpl.cs: line 265
at NHibernate.Impl.CriteriaImpl.List() in p:\nhibernate-core\src\NHibernate\Impl\CriteriaImpl.cs: line 276
The issue is because we are trying to use the alias "mk" which occurs 2 levels up of nested queries. Note that this should result in perfectly valid SQL.
I would also like to point out that the error thrown is very unfriendly. It would be good to throw a more descriptive error, e.g. "alias 'mk' cannot be found" as debugging this issue is painful.