After upgrading from NH2.1.2GA to NH3.0GA, several of our LINQ queries
that use the PredicateBuilder class (http://www.albahari.com/nutshell/
predicatebuilder.aspx) no longer work. The PredicateBuilder class is
used to aid in the construction of dynamically created Expressions
where an Expression must be initialized before looping through code to
add values to the Expression. The LINQ queries result in the
following error (full stack trace at the end of the post):
NHibernate.Hql.Ast.ANTLR.InvalidPathException : Invalid path:
'item.SerialNumber'
[.Where(NHibernate.Linq.NhQueryable`1[NHibernate.Test.NHSpecificTest.NHPred.Animal],
Quote((f, ) => (AndAlso(p1, (item, ) =>
(String.op_Equality(item.SerialNumber, p2))f))), )]
It seems as if the Expressions aren't being individually evaluated.
NH assigns the first variable, 'f', to the 'Animal' entity, but then
cannot associate the 'item' variable to the same entity even though
the 'item' variable does represent the 'Animal' entity. When viewing
the Expression Tree, the ParameterExpression elements are as follows:
ParameterExpression
- Name: String: "item"
- NodeType: ExpressionType: "Parameter"
- Type: Type: "Animal"
ParameterExpression
- Name: String: "f"
- NodeType: ExpressionType: "Parameter"
- Type: Type: "Animal"
Is this a bug in NHibernate or a user error?
I am using the Animal class and mapping files found in the NHibernate
unit test directories. My unit test is as follows:
[Test]
public void
NH30LinqQueryWithExpressionsDifferentInputParameterValueTest()
{
//Simulate data coming from web form.
string searchOnName = string.Empty;
const string searchOnSerialNumber = "444";
using (ISession session = this.OpenSession())
{
//Since we will be 'and-ing' our conditions, we can
just start with
a 'True' value to initialize
// the Expression and add all our conditions to it.
Expression<Func<Animal, bool>> criteria =
PredicateBuilder.True<Animal>(); // return f => true;
if (!string.IsNullOrEmpty(searchOnName))
//NOTE: The .And() method is an extension
method provided by
PredicateBuilder.
criteria = criteria.And(item =>
item.Description == searchOnName);
if (!string.IsNullOrEmpty(searchOnSerialNumber))
//NOTE: The .And() method is an extension
method provided by
PredicateBuilder.
criteria = criteria.And(item =>
item.SerialNumber ==
searchOnSerialNumber);
//Run the search.
if (null != criteria)
{
var animals =
session.Query<Animal>().Where(criteria).ToList();
Assert.AreEqual(1, animals.Count);
}
else
Assert.Fail("Criteria variable should not be
null.");
}
}
Full stack trace:
NHibernate.Hql.Ast.ANTLR.InvalidPathException : Invalid path:
'item.SerialNumber'
[.Where(NHibernate.Linq.NhQueryable`1[NHibernate.Test.NHSpecificTest.NHPred.Animal],
Quote((f, ) => (AndAlso(p1, (item, ) =>
(String.op_Equality(item.SerialNumber, p2))f))), )]
at
NHibernate.Hql.Ast.ANTLR.Util.LiteralProcessor.LookupConstant(DotNode
node)
at NHibernate.Hql.Ast.ANTLR.Tree.DotNode.Resolve(Boolean generateJoin,
Boolean implicitJoin, String classAlias, IASTNode parent)
at NHibernate.Hql.Ast.ANTLR.Tree.FromReferenceNode.Resolve(Boolean
generateJoin, Boolean implicitJoin)
at NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.Resolve(IASTNode node)
at NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.expr()
at NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.exprOrSubquery()
at NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.comparisonExpr()
at NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.logicalExpr()
at NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.logicalExpr()
at NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.whereClause()
at NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.unionedQuery()
at NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.query()
at NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.selectStatement()
at NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.statement()
at NHibernate.Hql.Ast.ANTLR.HqlSqlTranslator.Translate()
at NHibernate.Hql.Ast.ANTLR.QueryTranslatorImpl.Analyze(String
collectionRole)
at
NHibernate.Hql.Ast.ANTLR.QueryTranslatorImpl.DoCompile(IDictionary`2
replacements, Boolean shallow, String collectionRole)
at
NHibernate.Hql.Ast.ANTLR.ASTQueryTranslatorFactory.CreateQueryTranslators(IASTNode
ast, String queryIdentifier, String collectionRole, Boolean shallow,
IDictionary`2 filters, ISessionFactoryImplementor factory)
at
NHibernate.Hql.Ast.ANTLR.ASTQueryTranslatorFactory.CreateQueryTranslators(String
queryIdentifier, IQueryExpression queryExpression, String
collectionRole, Boolean shallow, IDictionary`2 filters,
ISessionFactoryImplementor factory)
at NHibernate.Engine.Query.HQLExpressionQueryPlan..ctor(String
expressionStr, IQueryExpression queryExpression, String
collectionRole, Boolean shallow, IDictionary`2 enabledFilters,
ISessionFactoryImplementor factory)
at NHibernate.Engine.Query.HQLExpressionQueryPlan..ctor(String
expressionStr, IQueryExpression queryExpression, Boolean shallow,
IDictionary`2 enabledFilters, ISessionFactoryImplementor factory)
at
NHibernate.Engine.Query.QueryPlanCache.GetHQLQueryPlan(IQueryExpression
queryExpression, Boolean shallow, IDictionary`2 enabledFilters)
at
NHibernate.Impl.AbstractSessionImpl.GetHQLQueryPlan(IQueryExpression
queryExpression, Boolean shallow)
at NHibernate.Impl.AbstractSessionImpl.CreateQuery(IQueryExpression
queryExpression)
at NHibernate.Linq.NhQueryProvider.PrepareQuery(Expression expression,
ref IQuery query, ref NhLinqExpression nhQuery)
at NHibernate.Linq.NhQueryProvider.Execute(Expression expression)
at NHibernate.Linq.NhQueryProvider.Execute(Expression expression)
at Remotion.Data.Linq.QueryableBase`1.GetEnumerator()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList(IEnumerable`1 source)
at
NHibernate.Test.NHSpecificTest.NHPred.LinqTest.NH30LinqQueryWithExpressionsDifferentInputParameterValueTest()
in LinqTest.cs: line 203
--
You received this message because you are subscribed to the Google Groups
"nhusers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/nhusers?hl=en.