Skip to content

Commit a842cbe

Browse files
authored
Reenable use of SelectClauseVisitor for subqueries (#3414)
1 parent 7681611 commit a842cbe

File tree

5 files changed

+33
-9
lines changed

5 files changed

+33
-9
lines changed

src/NHibernate.Test/Async/Linq/WhereTests.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,19 @@ where sheet.Users.Select(x => x.NullableEnum2 ?? value).Contains(value)
659659
Assert.That(query.Count, Is.EqualTo(1));
660660
}
661661

662+
[Test]
663+
public async Task TimesheetsWithProjectionInSubqueryAsync()
664+
{
665+
if (Dialect is MsSqlCeDialect)
666+
Assert.Ignore("Dialect is not supported");
667+
668+
var query = await ((from sheet in db.Timesheets
669+
where sheet.Users.Select(x => new { Id = x.Id, Name = x.Name }).Any(x => x.Id == 1)
670+
select sheet).ToListAsync());
671+
672+
Assert.That(query.Count, Is.EqualTo(2));
673+
}
674+
662675
[Test]
663676
public async Task ContainsSubqueryWithCoalesceStringEnumSelectAsync()
664677
{

src/NHibernate.Test/Linq/WhereTests.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -660,6 +660,19 @@ where sheet.Users.Select(x => x.NullableEnum2 ?? value).Contains(value)
660660
Assert.That(query.Count, Is.EqualTo(1));
661661
}
662662

663+
[Test]
664+
public void TimesheetsWithProjectionInSubquery()
665+
{
666+
if (Dialect is MsSqlCeDialect)
667+
Assert.Ignore("Dialect is not supported");
668+
669+
var query = (from sheet in db.Timesheets
670+
where sheet.Users.Select(x => new { Id = x.Id, Name = x.Name }).Any(x => x.Id == 1)
671+
select sheet).ToList();
672+
673+
Assert.That(query.Count, Is.EqualTo(2));
674+
}
675+
663676
[Test]
664677
public void ContainsSubqueryWithCoalesceStringEnumSelect()
665678
{

src/NHibernate/Linq/Visitors/QueryModelVisitor.cs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -476,13 +476,9 @@ public override void VisitSelectClause(SelectClause selectClause, QueryModel que
476476

477477
private HqlSelect GetSelectClause(Expression selectClause)
478478
{
479-
if (!_root)
480-
return _hqlTree.TreeBuilder.Select(
481-
HqlGeneratorExpressionVisitor.Visit(selectClause, VisitorParameters).AsExpression());
482-
483479
var visitor = new SelectClauseVisitor(typeof(object[]), VisitorParameters);
484480

485-
visitor.VisitSelector(selectClause);
481+
visitor.VisitSelector(selectClause, !_root);
486482

487483
if (visitor.ProjectionExpression != null)
488484
{

src/NHibernate/Linq/Visitors/SelectClauseNominator.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,13 @@ public SelectClauseHqlNominator(VisitorParameters parameters)
4343
_parameters = parameters;
4444
}
4545

46-
internal Expression Nominate(Expression expression)
46+
internal Expression Nominate(Expression expression, bool isSubQuery = false)
4747
{
4848
HqlCandidates = new HashSet<Expression>();
4949
ContainsUntranslatedMethodCalls = false;
5050
_canBeCandidate = true;
5151
_stateStack = new Stack<bool>();
52-
_stateStack.Push(false);
52+
_stateStack.Push(isSubQuery);
5353

5454
return Visit(expression);
5555
}

src/NHibernate/Linq/Visitors/SelectClauseVisitor.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ public IEnumerable<HqlExpression> GetHqlNodes()
3434
return _hqlTreeNodes;
3535
}
3636

37-
public void VisitSelector(Expression expression)
37+
public void VisitSelector(Expression expression) => VisitSelector(expression, false);
38+
39+
public void VisitSelector(Expression expression, bool isSubQuery)
3840
{
3941
var distinct = expression as NhDistinctExpression;
4042
if (distinct != null)
@@ -44,7 +46,7 @@ public void VisitSelector(Expression expression)
4446

4547
// Find the sub trees that can be expressed purely in HQL
4648
var nominator = new SelectClauseHqlNominator(_parameters);
47-
expression = nominator.Nominate(expression);
49+
expression = nominator.Nominate(expression, isSubQuery);
4850
_hqlNodes = nominator.HqlCandidates;
4951

5052
// Linq2SQL ignores calls to local methods. Linq2EF seems to not support

0 commit comments

Comments
 (0)