Skip to content

Commit d9528fe

Browse files
committed
Update IIsEntityDecider to use ExpressionsHelper.TryGetMappedType
1 parent 873feec commit d9528fe

File tree

3 files changed

+36
-11
lines changed

3 files changed

+36
-11
lines changed

src/NHibernate/Linq/ReWriters/AddJoinsReWriter.cs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
using System;
22
using System.Linq;
3+
using System.Linq.Expressions;
34
using NHibernate.Engine;
45
using NHibernate.Linq.Clauses;
56
using NHibernate.Linq.Visitors;
7+
using NHibernate.Util;
68
using Remotion.Linq;
79
using Remotion.Linq.Clauses;
810

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

1718
public class AddJoinsReWriter : NhQueryModelVisitorBase, IIsEntityDecider
@@ -24,8 +25,8 @@ private AddJoinsReWriter(ISessionFactoryImplementor sessionFactory, QueryModel q
2425
{
2526
_sessionFactory = sessionFactory;
2627
var joiner = new Joiner(queryModel);
27-
_memberExpressionJoinDetector = new MemberExpressionJoinDetector(this, joiner);
28-
_whereJoinDetector = new WhereJoinDetector(this, joiner);
28+
_memberExpressionJoinDetector = new MemberExpressionJoinDetector(this, joiner, _sessionFactory);
29+
_whereJoinDetector = new WhereJoinDetector(this, joiner, _sessionFactory);
2930
}
3031

3132
public static void ReWrite(QueryModel queryModel, VisitorParameters parameters)
@@ -59,15 +60,28 @@ public override void VisitNhHavingClause(NhHavingClause havingClause, QueryModel
5960
_whereJoinDetector.Transform(havingClause);
6061
}
6162

63+
// Since v5.3
64+
[Obsolete("This method has no usages and will be removed in a future version")]
6265
public bool IsEntity(System.Type type)
6366
{
6467
return _sessionFactory.GetImplementors(type.FullName).Any();
6568
}
6669

70+
// Since v5.3
71+
[Obsolete("This method has no usages and will be removed in a future version")]
6772
public bool IsIdentifier(System.Type type, string propertyName)
6873
{
6974
var metadata = _sessionFactory.GetClassMetadata(type);
7075
return metadata != null && propertyName.Equals(metadata.IdentifierPropertyName);
7176
}
77+
78+
bool IIsEntityDecider.IsEntity(MemberExpression expression, out bool isIdentifier)
79+
{
80+
isIdentifier =
81+
ExpressionsHelper.TryGetMappedType(_sessionFactory, expression, out var mappedType, out var entityPersister, out _, out var memberPath)
82+
&& entityPersister?.IdentifierPropertyName == memberPath;
83+
84+
return mappedType?.IsEntityType == true;
85+
}
7286
}
7387
}

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,21 +19,26 @@ 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)
3440
{
35-
var isIdentifier = _isEntityDecider.IsIdentifier(expression.Expression.Type, expression.Member.Name);
41+
var isEntity = _isEntityDecider.IsEntity(expression, out var isIdentifier);
3642
if (isIdentifier)
3743
_hasIdentifier = true;
3844
if (!isIdentifier)
@@ -43,7 +49,7 @@ protected override Expression VisitMember(MemberExpression expression)
4349
if (!isIdentifier)
4450
_memberExpressionDepth--;
4551

46-
if (_isEntityDecider.IsEntity(expression.Type) &&
52+
if (isEntity &&
4753
((_requiresJoinForNonIdentifier && !_hasIdentifier) || _memberExpressionDepth > 0) &&
4854
_joiner.CanAddJoin(expression))
4955
{

src/NHibernate/Linq/Visitors/WhereJoinDetector.cs

Lines changed: 9 additions & 4 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.Clauses;
67
using NHibernate.Linq.ReWriters;
78
using Remotion.Linq.Clauses;
@@ -62,6 +63,7 @@ internal class WhereJoinDetector : RelinqExpressionVisitor
6263
// 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.
6364
private readonly IIsEntityDecider _isEntityDecider;
6465
private readonly IJoiner _joiner;
66+
private readonly ISessionFactoryImplementor _sessionFactory;
6567

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

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

74-
internal WhereJoinDetector(IIsEntityDecider isEntityDecider, IJoiner joiner)
76+
internal WhereJoinDetector(
77+
IIsEntityDecider isEntityDecider,
78+
IJoiner joiner,
79+
ISessionFactoryImplementor sessionFactory)
7580
{
7681
_isEntityDecider = isEntityDecider;
7782
_joiner = joiner;
83+
_sessionFactory = sessionFactory;
7884
}
7985

8086
public void Transform(IClause whereClause)
@@ -296,8 +302,7 @@ protected override Expression VisitMember(MemberExpression expression)
296302
// I'm not sure what processing re-linq does to strange member expressions.
297303
// TODO: I suspect this code doesn't add the right joins for the last case.
298304

299-
var isIdentifier = _isEntityDecider.IsIdentifier(expression.Expression.Type, expression.Member.Name);
300-
305+
var isEntity = _isEntityDecider.IsEntity(expression, out var isIdentifier);
301306
if (!isIdentifier)
302307
_memberExpressionDepth++;
303308

@@ -307,7 +312,7 @@ protected override Expression VisitMember(MemberExpression expression)
307312
_memberExpressionDepth--;
308313

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

0 commit comments

Comments
 (0)