Skip to content

Commit 802f61b

Browse files
NH-3944 - preliminary work, Nh clauses eliminated.
1 parent 12278f1 commit 802f61b

File tree

13 files changed

+275
-298
lines changed

13 files changed

+275
-298
lines changed

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,5 +135,23 @@ public void SingleKeyGroupAndCountWithHavingClause()
135135
var hornRow = orderCounts.Single(row => row.CompanyName == "Around the Horn");
136136
Assert.That(hornRow.OrderCount, Is.EqualTo(13));
137137
}
138+
139+
[Test, Explicit("Demonstrate an unsupported case for PagingRewriter")]
140+
public void SingleKeyGroupAndCountWithHavingClausePagingAndOuterWhere()
141+
{
142+
var orderCounts = db.Orders
143+
.GroupBy(o => o.Customer.CompanyName)
144+
.Where(g => g.Count() > 10)
145+
.Select(g => new { CompanyName = g.Key, OrderCount = g.Count() })
146+
.OrderBy(oc => oc.CompanyName)
147+
.Skip(5)
148+
.Take(10)
149+
.Where(oc => oc.CompanyName.Contains("F"))
150+
.ToList();
151+
152+
Assert.That(orderCounts, Has.Count.EqualTo(3));
153+
var frankRow = orderCounts.Single(row => row.CompanyName == "Frankenversand");
154+
Assert.That(frankRow.OrderCount, Is.EqualTo(15));
155+
}
138156
}
139157
}

src/NHibernate/Linq/Clauses/NhHavingClause.cs

Lines changed: 0 additions & 19 deletions
This file was deleted.

src/NHibernate/Linq/Clauses/NhJoinClause.cs

Lines changed: 0 additions & 62 deletions
This file was deleted.

src/NHibernate/Linq/Clauses/NhWithClause.cs

Lines changed: 0 additions & 19 deletions
This file was deleted.

src/NHibernate/Linq/GroupBy/AggregatingGroupByRewriter.cs

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
using System.Collections.Generic;
33
using System.Linq;
44
using System.Linq.Expressions;
5-
using NHibernate.Linq.Clauses;
65
using NHibernate.Linq.ReWriters;
76
using NHibernate.Linq.Visitors;
87
using Remotion.Linq;
@@ -43,29 +42,26 @@ public static class AggregatingGroupByRewriter
4342
typeof (CacheableResultOperator)
4443
};
4544

46-
public static void ReWrite(QueryModel queryModel)
45+
public static void ReWrite(QueryModel queryModel, VisitorParameters parameters)
4746
{
48-
var subQueryExpression = queryModel.MainFromClause.FromExpression as SubQueryExpression;
49-
50-
if (subQueryExpression != null)
47+
if (queryModel.MainFromClause.FromExpression is SubQueryExpression subQueryExpression)
5148
{
5249
var operators = subQueryExpression.QueryModel.ResultOperators
5350
.Where(x => !QueryReferenceExpressionFlattener.FlattenableResultOperators.Contains(x.GetType()))
5451
.ToArray();
5552

5653
if (operators.Length == 1)
5754
{
58-
var groupBy = operators[0] as GroupResultOperator;
59-
if (groupBy != null)
55+
if (operators[0] is GroupResultOperator groupBy)
6056
{
61-
FlattenSubQuery(queryModel, subQueryExpression.QueryModel, groupBy);
57+
FlattenSubQuery(queryModel, subQueryExpression.QueryModel, groupBy, parameters);
6258
RemoveCostantGroupByKeys(queryModel, groupBy);
6359
}
6460
}
6561
}
6662
}
6763

68-
private static void FlattenSubQuery(QueryModel queryModel, QueryModel subQueryModel, GroupResultOperator groupBy)
64+
private static void FlattenSubQuery(QueryModel queryModel, QueryModel subQueryModel, GroupResultOperator groupBy, VisitorParameters parameters)
6965
{
7066
foreach (var resultOperator in queryModel.ResultOperators.Where(resultOperator => !AcceptableOuterResultOperators.Contains(resultOperator.GetType())))
7167
{
@@ -81,11 +77,9 @@ private static void FlattenSubQuery(QueryModel queryModel, QueryModel subQueryMo
8177
clause.TransformExpressions(s => GroupBySelectClauseRewriter.ReWrite(s, groupBy, subQueryModel));
8278

8379
//all outer where clauses actually are having clauses
84-
var whereClause = clause as WhereClause;
85-
if (whereClause != null)
80+
if (clause is WhereClause whereClause)
8681
{
87-
queryModel.BodyClauses.RemoveAt(i);
88-
queryModel.BodyClauses.Insert(i, new NhHavingClause(whereClause.Predicate));
82+
parameters.AddHavingClause(whereClause);
8983
}
9084
}
9185

src/NHibernate/Linq/GroupBy/PagingRewriter.cs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,16 @@ namespace NHibernate.Linq.GroupBy
99
{
1010
internal static class PagingRewriter
1111
{
12-
private static readonly System.Type[] PagingResultOperators = new[]
13-
{
14-
typeof (SkipResultOperator),
15-
typeof (TakeResultOperator),
16-
};
12+
private static readonly System.Type[] PagingResultOperators =
13+
new[]
14+
{
15+
typeof (SkipResultOperator),
16+
typeof (TakeResultOperator),
17+
};
1718

1819
public static void ReWrite(QueryModel queryModel)
1920
{
20-
var subQueryExpression = queryModel.MainFromClause.FromExpression as SubQueryExpression;
21-
22-
if (subQueryExpression != null &&
21+
if (queryModel.MainFromClause.FromExpression is SubQueryExpression subQueryExpression &&
2322
subQueryExpression.QueryModel.ResultOperators.All(x => PagingResultOperators.Contains(x.GetType())))
2423
{
2524
FlattenSubQuery(subQueryExpression, queryModel);
@@ -28,7 +27,7 @@ public static void ReWrite(QueryModel queryModel)
2827

2928
private static void FlattenSubQuery(SubQueryExpression subQueryExpression, QueryModel queryModel)
3029
{
31-
// we can not flattern subquery if outer query has body clauses.
30+
// we can not flatten subquery if outer query has body clauses.
3231
var subQueryModel = subQueryExpression.QueryModel;
3332
var subQueryMainFromClause = subQueryModel.MainFromClause;
3433
if (queryModel.BodyClauses.Count == 0)
@@ -46,9 +45,13 @@ private static void FlattenSubQuery(SubQueryExpression subQueryExpression, Query
4645
{
4746
var cro = new ContainsResultOperator(new QuerySourceReferenceExpression(subQueryMainFromClause));
4847

48+
// Cloning may cause having/join/with clauses listed in VisitorParameters to no more be matched.
49+
// Not a problem for now, because those clauses imply a projection, which is not supported
50+
// by the "new WhereClause(new SubQueryExpression(newSubQueryModel))" below. See
51+
// SingleKeyGroupAndCountWithHavingClausePagingAndOuterWhere test by example.
4952
var newSubQueryModel = subQueryModel.Clone();
5053
newSubQueryModel.ResultOperators.Add(cro);
51-
newSubQueryModel.ResultTypeOverride = typeof (bool);
54+
newSubQueryModel.ResultTypeOverride = typeof(bool);
5255

5356
var where = new WhereClause(new SubQueryExpression(newSubQueryModel));
5457
queryModel.BodyClauses.Add(where);

0 commit comments

Comments
 (0)