Skip to content

Linq queries with a condition after a projection on a collection fail #2512

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
cremor opened this issue Sep 3, 2020 · 0 comments
Closed

Comments

@cremor
Copy link
Contributor

cremor commented Sep 3, 2020

I've just updated from NHibernate 5.2.7 to 5.3.2 and now a few of my tests are failing. Although I get a few different exceptions, some of them seem to be related because they all only happen if a Linq query contains a specific condition after a projection on a collection (.SelectMany(x => x.Collection)).

Sample code:

Person singlePersonParameter = ...
Person[] personArrayParameter = new[] { singlePersonParameter };
long[] personIdsArrayParameter = personArrayParameter.Select(p => p.Id).ToArray();

// Works
result = Query<Person>()
   .Where(x => x == singlePersonParameter)
   .ToArray();

// Works
result = Query<Customer>()
   .SelectMany(x => x.Persons)
   .Where(x => x.Id == singlePersonParameter.Id)
   .ToArray();

// Fails with exception in NHibernate code (1)
result = Query<Customer>()
   .SelectMany(x => x.Persons)
   .Where(x => x == singlePersonParameter)
   .ToArray();

// Works
result = Query<Person>()
   .Where(x => personArrayParameter.Contains(x))
   .ToArray();

// Works
result = Query<Customer>()
   .SelectMany(x => x.Persons)
   .Where(x => personIdsArrayParameter.Contains(x.Id))
   .ToArray();

// Fails with exception in NHibernate code (2)
result = Query<Customer>()
   .SelectMany(x => x.Persons)
   .Where(x => personArrayParameter.Contains(x))
   .ToArray();

The exception (1) is

NHibernate.TypeMismatchException: 'left and right hand sides of a binary logic operator were incompatibile [My.Namespace.Person : System.Collections.Generic.ISet`1[[My.Namespace.Person, MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]](My.Namespace.Customer.Persons)]'

and the full stack is

NHibernate.dll!NHibernate.Hql.Ast.ANTLR.Tree.BinaryLogicOperatorNode.MutateRowValueConstructorSyntaxesIfNecessary(NHibernate.Type.IType lhsType, NHibernate.Type.IType rhsType) Line 95
NHibernate.dll!NHibernate.Hql.Ast.ANTLR.Tree.BinaryLogicOperatorNode.Initialize() Line 79
NHibernate.dll!NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.PrepareLogicOperator(NHibernate.Hql.Ast.ANTLR.Tree.IASTNode operatorNode) Line 956
NHibernate.dll!NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.comparisonExpr() Line 7831
NHibernate.dll!NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.logicalExpr() Line 6575
NHibernate.dll!NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.whereClause() Line 6250
NHibernate.dll!NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.unionedQuery() Line 1819
NHibernate.dll!NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.query() Line 1583
NHibernate.dll!NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.selectStatement() Line 432
NHibernate.dll!NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.statement() Line 310
NHibernate.dll!NHibernate.Hql.Ast.ANTLR.HqlSqlTranslator.Translate() Line 613
NHibernate.dll!NHibernate.Hql.Ast.ANTLR.QueryTranslatorImpl.Analyze(string collectionRole) Line 459
NHibernate.dll!NHibernate.Hql.Ast.ANTLR.QueryTranslatorImpl.DoCompile(System.Collections.Generic.IDictionary<string, string> replacements, bool shallow, string collectionRole) Line 361
NHibernate.dll!NHibernate.Hql.Ast.ANTLR.ASTQueryTranslatorFactory.CreateQueryTranslators(NHibernate.IQueryExpression queryExpression, NHibernate.Hql.Ast.ANTLR.Tree.IASTNode ast, string queryIdentifier, string collectionRole, bool shallow, System.Collections.Generic.IDictionary<string, NHibernate.IFilter> filters, NHibernate.Engine.ISessionFactoryImplementor factory) Line 43
NHibernate.dll!NHibernate.Hql.Ast.ANTLR.ASTQueryTranslatorFactory.CreateQueryTranslators(NHibernate.IQueryExpression queryExpression, string collectionRole, bool shallow, System.Collections.Generic.IDictionary<string, NHibernate.IFilter> filters, NHibernate.Engine.ISessionFactoryImplementor factory) Line 20
NHibernate.dll!NHibernate.Engine.Query.QueryPlanCache.GetHQLQueryPlan(NHibernate.IQueryExpression queryExpression, bool shallow, System.Collections.Generic.IDictionary<string, NHibernate.IFilter> enabledFilters) Line 63
NHibernate.dll!NHibernate.Impl.AbstractSessionImpl.GetHQLQueryPlan(NHibernate.IQueryExpression queryExpression, bool shallow) Line 584
NHibernate.dll!NHibernate.Impl.AbstractSessionImpl.CreateQuery(NHibernate.IQueryExpression queryExpression) Line 552
NHibernate.dll!NHibernate.Linq.DefaultQueryProvider.PrepareQuery(System.Linq.Expressions.Expression expression, out NHibernate.IQuery query) Line 208
NHibernate.dll!NHibernate.Linq.DefaultQueryProvider.ExecuteList<My.Namespace.Person>(System.Linq.Expressions.Expression expression) Line 107
NHibernate.dll!NHibernate.Linq.NhQueryable<My.Namespace.Person>.System.Collections.Generic.IEnumerable<My.Namespace.Person>.GetEnumerator() Line 65
System.Core.dll!System.Linq.Buffer<My.Namespace.Person>.Buffer(System.Collections.Generic.IEnumerable<My.Namespace.Person> source)
System.Core.dll!System.Linq.Enumerable.ToArray<My.Namespace.Person>(System.Collections.Generic.IEnumerable<My.Namespace.Person> source)

The exception (2) is System.InvalidOperationException: Sequence contains no elements. and the full stack is

System.Core.dll!System.Linq.Enumerable.First<string>(System.Collections.Generic.IEnumerable<string> source)
NHibernate.dll!NHibernate.SqlCommand.SqlCommandImpl.ResetParametersIndexesForTheCommand(int singleSqlParametersOffset) Line 111
NHibernate.dll!NHibernate.Loader.Loader.PrepareQueryCommand(NHibernate.Engine.QueryParameters queryParameters, bool scroll, NHibernate.Engine.ISessionImplementor session) Line 1441
NHibernate.dll!NHibernate.Loader.Loader.DoQuery(NHibernate.Engine.ISessionImplementor session, NHibernate.Engine.QueryParameters queryParameters, bool returnProxies, NHibernate.Transform.IResultTransformer forcedResultTransformer, NHibernate.Cache.QueryCacheResultBuilder queryCacheResultBuilder) Line 503
NHibernate.dll!NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(NHibernate.Engine.ISessionImplementor session, NHibernate.Engine.QueryParameters queryParameters, bool returnProxies, NHibernate.Transform.IResultTransformer forcedResultTransformer, NHibernate.Cache.QueryCacheResultBuilder queryCacheResultBuilder) Line 303
NHibernate.dll!NHibernate.Loader.Loader.DoList(NHibernate.Engine.ISessionImplementor session, NHibernate.Engine.QueryParameters queryParameters, NHibernate.Transform.IResultTransformer forcedResultTransformer, NHibernate.Cache.QueryCacheResultBuilder queryCacheResultBuilder) Line 1972
NHibernate.dll!NHibernate.Loader.Loader.ListIgnoreQueryCache(NHibernate.Engine.ISessionImplementor session, NHibernate.Engine.QueryParameters queryParameters) Line 1837
NHibernate.dll!NHibernate.Loader.Loader.List(NHibernate.Engine.ISessionImplementor session, NHibernate.Engine.QueryParameters queryParameters, System.Collections.Generic.ISet<string> querySpaces) Line 1825
NHibernate.dll!NHibernate.Loader.Hql.QueryLoader.List(NHibernate.Engine.ISessionImplementor session, NHibernate.Engine.QueryParameters queryParameters) Line 325
NHibernate.dll!NHibernate.Hql.Ast.ANTLR.QueryTranslatorImpl.List(NHibernate.Engine.ISessionImplementor session, NHibernate.Engine.QueryParameters queryParameters) Line 119
NHibernate.dll!NHibernate.Engine.Query.HQLQueryPlan.PerformList(NHibernate.Engine.QueryParameters queryParameters, NHibernate.Engine.ISessionImplementor session, System.Collections.IList results) Line 151
NHibernate.dll!NHibernate.Impl.SessionImpl.List(NHibernate.IQueryExpression queryExpression, NHibernate.Engine.QueryParameters queryParameters, System.Collections.IList results, object filterConnection) Line 554
NHibernate.dll!NHibernate.Impl.SessionImpl.List(NHibernate.IQueryExpression queryExpression, NHibernate.Engine.QueryParameters queryParameters, System.Collections.IList results) Line 524
NHibernate.dll!NHibernate.Impl.AbstractSessionImpl.List<My.Namespace.Person>(NHibernate.IQueryExpression query, NHibernate.Engine.QueryParameters parameters) Line 183
NHibernate.dll!NHibernate.Impl.AbstractQueryImpl2.List<My.Namespace.Person>() Line 108
NHibernate.dll!NHibernate.Linq.DefaultQueryProvider.ExecuteList<My.Namespace.Person>(System.Linq.Expressions.Expression expression) Line 114
NHibernate.dll!NHibernate.Linq.NhQueryable<My.Namespace.Person>.System.Collections.Generic.IEnumerable<My.Namespace.Person>.GetEnumerator() Line 65
System.Core.dll!System.Linq.Buffer<My.Namespace.Person>.Buffer(System.Collections.Generic.IEnumerable<My.Namespace.Person> source)
System.Core.dll!System.Linq.Enumerable.ToArray<My.Namespace.Person>(System.Collections.Generic.IEnumerable<My.Namespace.Person> source)
@fredericDelaporte fredericDelaporte added this to the 5.3.3 milestone Sep 6, 2020
@fredericDelaporte fredericDelaporte changed the title [5.3.x regression] Linq queries with a condition after a projection on a collection fail Linq queries with a condition after a projection on a collection fail Sep 6, 2020
@hazzik hazzik added the r: Fixed label Sep 9, 2020
@hazzik hazzik closed this as completed Sep 9, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants