Skip to content

Commit a5edf73

Browse files
committed
Proper from node detection
1 parent 6a762a4 commit a5edf73

File tree

4 files changed

+49
-36
lines changed

4 files changed

+49
-36
lines changed

src/NHibernate/Linq/IntermediateHqlTree.cs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -139,19 +139,13 @@ public void AddSelectClause(HqlTreeNode select)
139139

140140
public void AddFromLastChildClause(params HqlTreeNode[] nodes)
141141
{
142-
var fromChild = GetLastFromChildNode();
142+
var fromChild = _root.NodesPreOrder.OfType<HqlFrom>().First().Children.Last();
143143
foreach (var node in nodes)
144144
{
145145
fromChild.AddChild(node);
146146
}
147147
}
148148

149-
internal HqlTreeNode GetLastFromChildNode() =>
150-
_root.NodesPreOrder
151-
.First(x => x.AstNode.Type == HqlSqlWalker.FROM)
152-
.Children
153-
.Last();
154-
155149
public void AddInsertClause(HqlIdent target, HqlRange columnSpec)
156150
{
157151
var into = _insertRoot.NodesPreOrder.OfType<HqlInto>().Single();

src/NHibernate/Linq/Visitors/JoinBuilder.cs

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
using Remotion.Linq;
55
using Remotion.Linq.Clauses;
66
using Remotion.Linq.Clauses.Expressions;
7-
using Remotion.Linq.Parsing;
87

98
namespace NHibernate.Linq.Visitors
109
{
@@ -76,23 +75,5 @@ private void AddJoin(QueryModel queryModel, NhJoinClause joinClause)
7675
{
7776
queryModel.BodyClauses.Add(joinClause);
7877
}
79-
80-
private class QuerySourceExtractor : RelinqExpressionVisitor
81-
{
82-
private IQuerySource _querySource;
83-
84-
public static IQuerySource GetQuerySource(Expression expression)
85-
{
86-
var sourceExtractor = new QuerySourceExtractor();
87-
sourceExtractor.Visit(expression);
88-
return sourceExtractor._querySource;
89-
}
90-
91-
protected override Expression VisitQuerySourceReference(QuerySourceReferenceExpression expression)
92-
{
93-
_querySource = expression.ReferencedQuerySource;
94-
return base.VisitQuerySourceReference(expression);
95-
}
96-
}
9778
}
9879
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using System.Linq.Expressions;
2+
using Remotion.Linq.Clauses;
3+
using Remotion.Linq.Clauses.Expressions;
4+
using Remotion.Linq.Parsing;
5+
6+
namespace NHibernate.Linq.Visitors
7+
{
8+
internal class QuerySourceExtractor : RelinqExpressionVisitor
9+
{
10+
private IQuerySource _querySource;
11+
12+
public static IQuerySource GetQuerySource(Expression expression)
13+
{
14+
var sourceExtractor = new QuerySourceExtractor();
15+
sourceExtractor.Visit(expression);
16+
return sourceExtractor._querySource;
17+
}
18+
19+
protected override Expression VisitQuerySourceReference(QuerySourceReferenceExpression expression)
20+
{
21+
_querySource = expression.ReferencedQuerySource;
22+
return base.VisitQuerySourceReference(expression);
23+
}
24+
}
25+
}

src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessFetch.cs

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using NHibernate.Hql.Ast.ANTLR;
55
using NHibernate.Persister.Entity;
66
using NHibernate.Type;
7+
using Remotion.Linq.Clauses.StreamedData;
78
using Remotion.Linq.EagerFetching;
89

910
namespace NHibernate.Linq.Visitors.ResultOperatorProcessors
@@ -12,20 +13,32 @@ public class ProcessFetch
1213
{
1314
public void Process(FetchRequestBase resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree)
1415
{
15-
var lastFromNode = tree.GetLastFromChildNode();
16-
Process(resultOperator, queryModelVisitor, tree, lastFromNode, GetNodeAlias(lastFromNode));
16+
var selector = ((StreamedSequenceInfo) queryModelVisitor.PreviousEvaluationType).ItemExpression;
17+
var querySource = QuerySourceExtractor.GetQuerySource(selector);
18+
var sourceAlias = queryModelVisitor.VisitorParameters.QuerySourceNamer.GetName(querySource);
19+
Process(resultOperator, queryModelVisitor, tree, GetFromNodeByAlias(tree, sourceAlias), sourceAlias);
1720
}
1821

19-
private static string GetNodeAlias(HqlTreeNode lastFrom)
22+
private static HqlTreeNode GetFromNodeByAlias(IntermediateHqlTree tree, string sourceAlias)
2023
{
21-
return lastFrom.Children.Select(x => x.AstNode)
24+
return tree.Root.NodesPreOrder
25+
.First(x => x.AstNode.Type == HqlSqlWalker.FROM).Children
26+
.First(x => GetNodeAlias(x) == sourceAlias);
27+
}
28+
29+
private static string GetNodeAlias(HqlTreeNode fromNode)
30+
{
31+
return fromNode.Children
32+
.Select(x => x.AstNode)
2233
.First(x => x.Type == HqlSqlWalker.ALIAS)
2334
.Text;
2435
}
2536

37+
// Since v5.5
38+
[Obsolete("This method is not used and will be removed in a future version.")]
2639
public void Process(FetchRequestBase resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree, string sourceAlias)
2740
{
28-
Process(resultOperator, queryModelVisitor, tree, null, sourceAlias);
41+
Process(resultOperator, queryModelVisitor, tree, GetFromNodeByAlias(tree, sourceAlias), sourceAlias);
2942
}
3043

3144
private void Process(
@@ -72,13 +85,12 @@ private void Process(
7285
propType = metadata.GetPropertyType(resultOperator.RelationMember.Name);
7386
}
7487
}
75-
88+
7689
if (propType != null && !propType.IsAssociationType)
7790
{
7891
if (currentNode == null)
7992
{
80-
currentNode = tree.GetLastFromChildNode()
81-
?? throw new InvalidOperationException($"Property {resultOperator.RelationMember.Name} cannot be fetched for this type of query.");
93+
throw new InvalidOperationException($"Property {resultOperator.RelationMember.Name} cannot be fetched for this type of query.");
8294
}
8395

8496
currentNode.AddChild(tree.TreeBuilder.Fetch());
@@ -89,12 +101,13 @@ private void Process(
89101
{
90102
if (componentType == null)
91103
{
92-
componentType = propType as ComponentType;
93-
if (componentType == null)
104+
if (!propType.IsComponentType)
94105
{
95106
throw new InvalidOperationException(
96107
$"Property {innerFetch.RelationMember.Name} cannot be fetched from a non component type property {resultOperator.RelationMember.Name}.");
97108
}
109+
110+
componentType = (ComponentType) propType;
98111
}
99112

100113
var subTypeIndex = componentType.GetPropertyIndex(innerFetch.RelationMember.Name);

0 commit comments

Comments
 (0)