Skip to content

Commit c9721e9

Browse files
committed
Update IIsEntityDecider to use ExpressionsHelper.TryGetMappedType
1 parent 697b6f7 commit c9721e9

File tree

3 files changed

+36
-13
lines changed

3 files changed

+36
-13
lines changed

src/NHibernate/Linq/ReWriters/AddJoinsReWriter.cs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
using System;
22
using System.Collections.Specialized;
33
using System.Linq;
4+
using System.Linq.Expressions;
45
using NHibernate.Engine;
56
using NHibernate.Linq.Clauses;
67
using NHibernate.Linq.Visitors;
8+
using NHibernate.Util;
79
using Remotion.Linq;
810
using Remotion.Linq.Clauses;
911

1012
namespace NHibernate.Linq.ReWriters
1113
{
1214
internal interface IIsEntityDecider
1315
{
14-
bool IsEntity(System.Type type);
15-
bool IsIdentifier(System.Type type, string propertyName);
16+
bool IsEntity(MemberExpression expression, out bool isIdentifier);
1617
}
1718

1819
public class AddJoinsReWriter : NhQueryModelVisitorBase, IIsEntityDecider
@@ -26,8 +27,8 @@ private AddJoinsReWriter(ISessionFactoryImplementor sessionFactory, QueryModel q
2627
{
2728
_sessionFactory = sessionFactory;
2829
var joiner = new Joiner(queryModel, AddJoin);
29-
_memberExpressionJoinDetector = new MemberExpressionJoinDetector(this, joiner);
30-
_whereJoinDetector = new WhereJoinDetector(this, joiner);
30+
_memberExpressionJoinDetector = new MemberExpressionJoinDetector(this, joiner, _sessionFactory);
31+
_whereJoinDetector = new WhereJoinDetector(this, joiner, _sessionFactory);
3132
}
3233

3334
public static void ReWrite(QueryModel queryModel, VisitorParameters parameters)
@@ -77,11 +78,15 @@ public override void VisitJoinClause(JoinClause joinClause, QueryModel queryMode
7778
_currentJoin = null;
7879
}
7980

81+
// Since v5.3
82+
[Obsolete("This method has no usages and will be removed in a future version")]
8083
public bool IsEntity(System.Type type)
8184
{
8285
return _sessionFactory.GetImplementors(type.FullName).Any();
8386
}
8487

88+
// Since v5.3
89+
[Obsolete("This method has no usages and will be removed in a future version")]
8590
public bool IsIdentifier(System.Type type, string propertyName)
8691
{
8792
var metadata = _sessionFactory.GetClassMetadata(type);
@@ -99,5 +104,14 @@ private void AddJoin(QueryModel queryModel, NhJoinClause joinClause)
99104

100105
queryModel.BodyClauses.Add(joinClause);
101106
}
107+
108+
bool IIsEntityDecider.IsEntity(MemberExpression expression, out bool isIdentifier)
109+
{
110+
isIdentifier =
111+
ExpressionsHelper.TryGetMappedType(_sessionFactory, expression, out var mappedType, out var entityPersister, out _, out var memberPath)
112+
&& entityPersister?.IdentifierPropertyName == memberPath;
113+
114+
return mappedType?.IsEntityType == true;
115+
}
102116
}
103117
}

src/NHibernate/Linq/Visitors/MemberExpressionJoinDetector.cs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System.Collections;
22
using System.Collections.Generic;
33
using System.Linq.Expressions;
4+
using NHibernate.Engine;
45
using NHibernate.Linq.Expressions;
56
using NHibernate.Linq.ReWriters;
67
using Remotion.Linq.Clauses;
@@ -18,16 +19,21 @@ internal class MemberExpressionJoinDetector : RelinqExpressionVisitor
1819
{
1920
private readonly IIsEntityDecider _isEntityDecider;
2021
private readonly IJoiner _joiner;
22+
private readonly ISessionFactoryImplementor _sessionFactory;
2123

2224
private bool _requiresJoinForNonIdentifier;
2325
private bool _preventJoinsInConditionalTest;
2426
private bool _hasIdentifier;
2527
private int _memberExpressionDepth;
2628

27-
public MemberExpressionJoinDetector(IIsEntityDecider isEntityDecider, IJoiner joiner)
29+
public MemberExpressionJoinDetector(
30+
IIsEntityDecider isEntityDecider,
31+
IJoiner joiner,
32+
ISessionFactoryImplementor sessionFactory)
2833
{
2934
_isEntityDecider = isEntityDecider;
3035
_joiner = joiner;
36+
_sessionFactory = sessionFactory;
3137
}
3238

3339
protected override Expression VisitMember(MemberExpression expression)
@@ -39,7 +45,7 @@ protected override Expression VisitMember(MemberExpression expression)
3945
return base.VisitMember(expression);
4046
}
4147

42-
var isIdentifier = _isEntityDecider.IsIdentifier(expression.Expression.Type, expression.Member.Name);
48+
var isEntity = _isEntityDecider.IsEntity(expression, out var isIdentifier);
4349
if (isIdentifier)
4450
_hasIdentifier = true;
4551
if (!isIdentifier)
@@ -50,7 +56,7 @@ protected override Expression VisitMember(MemberExpression expression)
5056
if (!isIdentifier)
5157
_memberExpressionDepth--;
5258

53-
if (_isEntityDecider.IsEntity(expression.Type) &&
59+
if (isEntity &&
5460
((_requiresJoinForNonIdentifier && !_hasIdentifier) || _memberExpressionDepth > 0) &&
5561
_joiner.CanAddJoin(expression))
5662
{

src/NHibernate/Linq/Visitors/WhereJoinDetector.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.Linq;
44
using System.Linq.Expressions;
5+
using NHibernate.Engine;
56
using NHibernate.Linq.ReWriters;
67
using Remotion.Linq.Clauses;
78
using Remotion.Linq.Clauses.Expressions;
@@ -61,6 +62,7 @@ internal class WhereJoinDetector : RelinqExpressionVisitor
6162
// TODO: There are a number of types of expressions that we didn't handle here due to time constraints. For example, the ?: operator could be checked easily.
6263
private readonly IIsEntityDecider _isEntityDecider;
6364
private readonly IJoiner _joiner;
65+
private readonly ISessionFactoryImplementor _sessionFactory;
6466

6567
private readonly Stack<bool> _handled = new Stack<bool>();
6668

@@ -70,10 +72,14 @@ internal class WhereJoinDetector : RelinqExpressionVisitor
7072
// The following is used for member expressions traversal.
7173
private int _memberExpressionDepth;
7274

73-
internal WhereJoinDetector(IIsEntityDecider isEntityDecider, IJoiner joiner)
75+
internal WhereJoinDetector(
76+
IIsEntityDecider isEntityDecider,
77+
IJoiner joiner,
78+
ISessionFactoryImplementor sessionFactory)
7479
{
7580
_isEntityDecider = isEntityDecider;
7681
_joiner = joiner;
82+
_sessionFactory = sessionFactory;
7783
}
7884

7985
public Expression Transform(Expression expression)
@@ -314,10 +320,7 @@ protected override Expression VisitMember(MemberExpression expression)
314320
return base.VisitMember(expression);
315321
}
316322

317-
var isIdentifier = _isEntityDecider.IsIdentifier(
318-
expression.Expression.Type,
319-
expression.Member.Name);
320-
323+
var isEntity = _isEntityDecider.IsEntity(expression, out var isIdentifier);
321324
if (!isIdentifier)
322325
_memberExpressionDepth++;
323326

@@ -327,7 +330,7 @@ protected override Expression VisitMember(MemberExpression expression)
327330
_memberExpressionDepth--;
328331

329332
ExpressionValues values = _values.Pop().Operation(pvs => pvs.MemberAccess(expression.Type));
330-
if (_isEntityDecider.IsEntity(expression.Type))
333+
if (isEntity)
331334
{
332335
// Don't add joins for things like a.B == a.C where B and C are entities.
333336
// We only need to join B when there's something like a.B.D.

0 commit comments

Comments
 (0)