Skip to content

Commit 1386cf4

Browse files
committed
Improve generated SQL for nested Any.
1 parent e1579a1 commit 1386cf4

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed

src/NHibernate.Test/Linq/ByMethod/AnyTests.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,5 +75,27 @@ public void AnyWithFetchInSubQuery()
7575
}
7676
);
7777
}
78+
79+
[Test(Description = "GH2479")]
80+
public void NestedAnyWithPaging()
81+
{
82+
using (var sqlSpy = new SqlLogSpy())
83+
{
84+
var ordersQuery = db.Orders
85+
.Where(x => x.Employee.EmployeeId > 5)
86+
.OrderBy(x => x.OrderId)
87+
.Take(2);
88+
89+
var orderLines = db.OrderLines
90+
.Where(x => ordersQuery.Any(o => o == x.Order))
91+
.OrderBy(x => x.Id)
92+
.ToList();
93+
94+
var sql = sqlSpy.GetWholeLog();
95+
96+
Assert.That(orderLines.Count, Is.EqualTo(6), nameof(orderLines));
97+
Assert.That(GetTotalOccurrences(sql, "select"), Is.EqualTo(2));
98+
}
99+
}
78100
}
79101
}

src/NHibernate/Linq/GroupBy/PagingRewriter.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Linq;
2+
using System.Linq.Expressions;
23
using NHibernate.Linq.Visitors;
34
using Remotion.Linq;
45
using Remotion.Linq.Clauses;
@@ -42,6 +43,31 @@ private static void FlattenSubQuery(SubQueryExpression subQueryExpression, Query
4243
var visitor1 = new PagingRewriterSelectClauseVisitor(queryModel.MainFromClause);
4344
queryModel.SelectClause.TransformExpressions(visitor1.Swap);
4445
}
46+
else if (queryModel.ResultOperators.Count == 1 && queryModel.ResultOperators[0] is AnyResultOperator &&
47+
queryModel.BodyClauses.Count == 1 && queryModel.BodyClauses[0] is WhereClause whereClause &&
48+
whereClause.Predicate is BinaryExpression whereClausePredicate &&
49+
new[] {whereClausePredicate.Left, whereClausePredicate.Right}.Count(x => x.NodeType == ExpressionType.MemberAccess) == 1)
50+
{
51+
var joinOnBodyClause = whereClausePredicate.Right.NodeType == ExpressionType.MemberAccess
52+
? whereClausePredicate.Right
53+
: whereClausePredicate.Left;
54+
var cro = new ContainsResultOperator(joinOnBodyClause);
55+
56+
queryModel.BodyClauses.Clear();
57+
foreach (var orderByClause in subQueryModel.BodyClauses)
58+
{
59+
queryModel.BodyClauses.Add(orderByClause);
60+
}
61+
62+
queryModel.ResultOperators.Clear();
63+
foreach (var resultOperator in subQueryModel.ResultOperators)
64+
{
65+
queryModel.ResultOperators.Add(resultOperator);
66+
}
67+
68+
queryModel.ResultOperators.Add(cro);
69+
queryModel.ResultTypeOverride = typeof(bool);
70+
}
4571
else
4672
{
4773
var cro = new ContainsResultOperator(new QuerySourceReferenceExpression(subQueryMainFromClause));

0 commit comments

Comments
 (0)