diff --git a/src/NHibernate.Test/Async/Linq/WhereTests.cs b/src/NHibernate.Test/Async/Linq/WhereTests.cs index aceda381352..365ad00de7f 100644 --- a/src/NHibernate.Test/Async/Linq/WhereTests.cs +++ b/src/NHibernate.Test/Async/Linq/WhereTests.cs @@ -659,6 +659,19 @@ where sheet.Users.Select(x => x.NullableEnum2 ?? value).Contains(value) Assert.That(query.Count, Is.EqualTo(1)); } + [Test] + public async Task TimesheetsWithProjectionInSubqueryAsync() + { + if (Dialect is MsSqlCeDialect) + Assert.Ignore("Dialect is not supported"); + + var query = await ((from sheet in db.Timesheets + where sheet.Users.Select(x => new { Id = x.Id, Name = x.Name }).Any(x => x.Id == 1) + select sheet).ToListAsync()); + + Assert.That(query.Count, Is.EqualTo(2)); + } + [Test] public async Task ContainsSubqueryWithCoalesceStringEnumSelectAsync() { diff --git a/src/NHibernate.Test/Linq/WhereTests.cs b/src/NHibernate.Test/Linq/WhereTests.cs index 5fffc56c052..90981dbc4d1 100644 --- a/src/NHibernate.Test/Linq/WhereTests.cs +++ b/src/NHibernate.Test/Linq/WhereTests.cs @@ -660,6 +660,19 @@ where sheet.Users.Select(x => x.NullableEnum2 ?? value).Contains(value) Assert.That(query.Count, Is.EqualTo(1)); } + [Test] + public void TimesheetsWithProjectionInSubquery() + { + if (Dialect is MsSqlCeDialect) + Assert.Ignore("Dialect is not supported"); + + var query = (from sheet in db.Timesheets + where sheet.Users.Select(x => new { Id = x.Id, Name = x.Name }).Any(x => x.Id == 1) + select sheet).ToList(); + + Assert.That(query.Count, Is.EqualTo(2)); + } + [Test] public void ContainsSubqueryWithCoalesceStringEnumSelect() { diff --git a/src/NHibernate/Linq/Visitors/QueryModelVisitor.cs b/src/NHibernate/Linq/Visitors/QueryModelVisitor.cs index c9f2a054bb1..43720cb12fb 100644 --- a/src/NHibernate/Linq/Visitors/QueryModelVisitor.cs +++ b/src/NHibernate/Linq/Visitors/QueryModelVisitor.cs @@ -476,13 +476,9 @@ public override void VisitSelectClause(SelectClause selectClause, QueryModel que private HqlSelect GetSelectClause(Expression selectClause) { - if (!_root) - return _hqlTree.TreeBuilder.Select( - HqlGeneratorExpressionVisitor.Visit(selectClause, VisitorParameters).AsExpression()); - var visitor = new SelectClauseVisitor(typeof(object[]), VisitorParameters); - visitor.VisitSelector(selectClause); + visitor.VisitSelector(selectClause, !_root); if (visitor.ProjectionExpression != null) { diff --git a/src/NHibernate/Linq/Visitors/SelectClauseNominator.cs b/src/NHibernate/Linq/Visitors/SelectClauseNominator.cs index 52bf954101d..0ab0dc25e4d 100644 --- a/src/NHibernate/Linq/Visitors/SelectClauseNominator.cs +++ b/src/NHibernate/Linq/Visitors/SelectClauseNominator.cs @@ -43,13 +43,13 @@ public SelectClauseHqlNominator(VisitorParameters parameters) _parameters = parameters; } - internal Expression Nominate(Expression expression) + internal Expression Nominate(Expression expression, bool isSubQuery = false) { HqlCandidates = new HashSet(); ContainsUntranslatedMethodCalls = false; _canBeCandidate = true; _stateStack = new Stack(); - _stateStack.Push(false); + _stateStack.Push(isSubQuery); return Visit(expression); } diff --git a/src/NHibernate/Linq/Visitors/SelectClauseVisitor.cs b/src/NHibernate/Linq/Visitors/SelectClauseVisitor.cs index df1cdfb3daa..a5155415dfd 100644 --- a/src/NHibernate/Linq/Visitors/SelectClauseVisitor.cs +++ b/src/NHibernate/Linq/Visitors/SelectClauseVisitor.cs @@ -34,7 +34,9 @@ public IEnumerable GetHqlNodes() return _hqlTreeNodes; } - public void VisitSelector(Expression expression) + public void VisitSelector(Expression expression) => VisitSelector(expression, false); + + public void VisitSelector(Expression expression, bool isSubQuery) { var distinct = expression as NhDistinctExpression; if (distinct != null) @@ -44,7 +46,7 @@ public void VisitSelector(Expression expression) // Find the sub trees that can be expressed purely in HQL var nominator = new SelectClauseHqlNominator(_parameters); - expression = nominator.Nominate(expression); + expression = nominator.Nominate(expression, isSubQuery); _hqlNodes = nominator.HqlCandidates; // Linq2SQL ignores calls to local methods. Linq2EF seems to not support