Skip to content

Commit d77e6f4

Browse files
committed
Code review changes
1 parent c9721e9 commit d77e6f4

File tree

7 files changed

+31
-18
lines changed

7 files changed

+31
-18
lines changed

src/NHibernate.DomainModel/Northwind/Entities/Animal.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ public class Animal
1212
public virtual Animal Father { get; set; }
1313
public virtual IList<Animal> Children { get; set; }
1414
public virtual string SerialNumber { get; set; }
15-
}
15+
16+
public virtual Animal FatherOrMother => Father ?? Mother;
17+
}
1618

1719
public abstract class Reptile : Animal
1820
{
@@ -30,4 +32,4 @@ public abstract class Mammal : Animal
3032
public class Dog : Mammal { }
3133

3234
public class Cat : Mammal { }
33-
}
35+
}

src/NHibernate.Test/Async/Linq/SelectionTests.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,14 @@ public async Task CanSelectFirstElementFromChildCollectionAsync()
289289
}
290290
}
291291

292+
[Test]
293+
public async Task CanSelectNotMappedEntityPropertyAsync()
294+
{
295+
var list = await (db.Animals.Where(o => o.Mother != null).Select(o => o.FatherOrMother.SerialNumber).ToListAsync());
296+
297+
Assert.That(list, Has.Count.GreaterThan(0));
298+
}
299+
292300
[Test]
293301
public async Task CanProjectWithCastAsync()
294302
{

src/NHibernate.Test/Linq/SelectionTests.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,14 @@ public void CanSelectWrappedType()
328328
Assert.IsTrue(query.ToArray().Length > 0);
329329
}
330330

331+
[Test]
332+
public void CanSelectNotMappedEntityProperty()
333+
{
334+
var list = db.Animals.Where(o => o.Mother != null).Select(o => o.FatherOrMother.SerialNumber).ToList();
335+
336+
Assert.That(list, Has.Count.GreaterThan(0));
337+
}
338+
331339
[Test]
332340
public void CanProjectWithCast()
333341
{

src/NHibernate/Linq/ReWriters/AddJoinsReWriter.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ private AddJoinsReWriter(ISessionFactoryImplementor sessionFactory, QueryModel q
2727
{
2828
_sessionFactory = sessionFactory;
2929
var joiner = new Joiner(queryModel, AddJoin);
30-
_memberExpressionJoinDetector = new MemberExpressionJoinDetector(this, joiner, _sessionFactory);
31-
_whereJoinDetector = new WhereJoinDetector(this, joiner, _sessionFactory);
30+
_memberExpressionJoinDetector = new MemberExpressionJoinDetector(this, joiner);
31+
_whereJoinDetector = new WhereJoinDetector(this, joiner);
3232
}
3333

3434
public static void ReWrite(QueryModel queryModel, VisitorParameters parameters)

src/NHibernate/Linq/Visitors/MemberExpressionJoinDetector.cs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,16 @@ internal class MemberExpressionJoinDetector : RelinqExpressionVisitor
1919
{
2020
private readonly IIsEntityDecider _isEntityDecider;
2121
private readonly IJoiner _joiner;
22-
private readonly ISessionFactoryImplementor _sessionFactory;
2322

2423
private bool _requiresJoinForNonIdentifier;
2524
private bool _preventJoinsInConditionalTest;
2625
private bool _hasIdentifier;
2726
private int _memberExpressionDepth;
2827

29-
public MemberExpressionJoinDetector(
30-
IIsEntityDecider isEntityDecider,
31-
IJoiner joiner,
32-
ISessionFactoryImplementor sessionFactory)
28+
public MemberExpressionJoinDetector(IIsEntityDecider isEntityDecider, IJoiner joiner)
3329
{
3430
_isEntityDecider = isEntityDecider;
3531
_joiner = joiner;
36-
_sessionFactory = sessionFactory;
3732
}
3833

3934
protected override Expression VisitMember(MemberExpression expression)

src/NHibernate/Linq/Visitors/SelectClauseNominator.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Linq.Expressions;
4+
using NHibernate.Engine;
45
using NHibernate.Linq.Functions;
56
using NHibernate.Linq.Expressions;
67
using NHibernate.Util;
@@ -15,6 +16,7 @@ namespace NHibernate.Linq.Visitors
1516
class SelectClauseHqlNominator : RelinqExpressionVisitor
1617
{
1718
private readonly ILinqToHqlGeneratorsRegistry _functionRegistry;
19+
private readonly ISessionFactoryImplementor _sessionFactory;
1820

1921
/// <summary>
2022
/// The expression parts that can be converted to pure HQL.
@@ -35,6 +37,7 @@ class SelectClauseHqlNominator : RelinqExpressionVisitor
3537
public SelectClauseHqlNominator(VisitorParameters parameters)
3638
{
3739
_functionRegistry = parameters.SessionFactory.Settings.LinqToHqlGeneratorsRegistry;
40+
_sessionFactory = parameters.SessionFactory;
3841
}
3942

4043
internal Expression Nominate(Expression expression)
@@ -168,8 +171,10 @@ private bool CanBeEvaluatedInHqlSelectStatement(Expression expression, bool proj
168171
return projectConstantsInHql;
169172
}
170173

171-
// Assume all is good
172-
return true;
174+
return !(expression is MemberExpression memberExpression) || // Assume all is good
175+
// Evaluate only expressions that represent a mapped property
176+
ExpressionsHelper.TryGetMappedType(_sessionFactory, expression, out _, out _, out _, out _) ||
177+
_functionRegistry.TryGetGenerator(memberExpression.Member, out _);
173178
}
174179

175180
private static bool CanBeEvaluatedInHqlStatementShortcut(Expression expression)

src/NHibernate/Linq/Visitors/WhereJoinDetector.cs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ internal class WhereJoinDetector : RelinqExpressionVisitor
6262
// 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.
6363
private readonly IIsEntityDecider _isEntityDecider;
6464
private readonly IJoiner _joiner;
65-
private readonly ISessionFactoryImplementor _sessionFactory;
6665

6766
private readonly Stack<bool> _handled = new Stack<bool>();
6867

@@ -72,14 +71,10 @@ internal class WhereJoinDetector : RelinqExpressionVisitor
7271
// The following is used for member expressions traversal.
7372
private int _memberExpressionDepth;
7473

75-
internal WhereJoinDetector(
76-
IIsEntityDecider isEntityDecider,
77-
IJoiner joiner,
78-
ISessionFactoryImplementor sessionFactory)
74+
internal WhereJoinDetector(IIsEntityDecider isEntityDecider, IJoiner joiner)
7975
{
8076
_isEntityDecider = isEntityDecider;
8177
_joiner = joiner;
82-
_sessionFactory = sessionFactory;
8378
}
8479

8580
public Expression Transform(Expression expression)

0 commit comments

Comments
 (0)