Skip to content

Commit 1793699

Browse files
authored
Fix table group join issue with subclasses (#3109)
1 parent 8f7cadd commit 1793699

File tree

3 files changed

+29
-3
lines changed

3 files changed

+29
-3
lines changed

src/NHibernate.Test/Async/Linq/ByMethod/JoinTests.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,19 @@ from o2 in db.Animals.Where(x => x.BodyWeight > 50)
299299
select new {o, o2}).Take(1).ToListAsync());
300300
}
301301

302+
[Test]
303+
public async Task CanInnerJoinOnEntityWithSubclassesAsync()
304+
{
305+
//inner joined animal is not used in output (no need to join subclasses)
306+
var resultsFromOuter1 = await (db.Animals.Join(db.Animals, o => o.Id, i => i.Id, (o, i) => o).Take(1).ToListAsync());
307+
308+
//inner joined mammal is not used in output (but subclass join is needed for mammal)
309+
var resultsFromOuter2 = await (db.Animals.Join(db.Mammals, o => o.Id, i => i.Id, (o, i) => o).Take(1).ToListAsync());
310+
311+
//inner joined animal is used in output (all subclass joins are required)
312+
var resultsFromInner1 = await (db.Animals.Join(db.Animals, o => o.Id, i => i.Id, (o, i) => i).Take(1).ToListAsync());
313+
}
314+
302315
[Test(Description = "GH-2580")]
303316
public async Task CanInnerJoinOnSubclassWithBaseTableReferenceInOnClauseAsync()
304317
{

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,19 @@ from o2 in db.Animals.Where(x => x.BodyWeight > 50)
287287
select new {o, o2}).Take(1).ToList();
288288
}
289289

290+
[Test]
291+
public void CanInnerJoinOnEntityWithSubclasses()
292+
{
293+
//inner joined animal is not used in output (no need to join subclasses)
294+
var resultsFromOuter1 = db.Animals.Join(db.Animals, o => o.Id, i => i.Id, (o, i) => o).Take(1).ToList();
295+
296+
//inner joined mammal is not used in output (but subclass join is needed for mammal)
297+
var resultsFromOuter2 = db.Animals.Join(db.Mammals, o => o.Id, i => i.Id, (o, i) => o).Take(1).ToList();
298+
299+
//inner joined animal is used in output (all subclass joins are required)
300+
var resultsFromInner1 = db.Animals.Join(db.Animals, o => o.Id, i => i.Id, (o, i) => i).Take(1).ToList();
301+
}
302+
290303
[Test(Description = "GH-2580")]
291304
public void CanInnerJoinOnSubclassWithBaseTableReferenceInOnClause()
292305
{

src/NHibernate/Engine/TableGroupJoinHelper.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ internal class TableGroupJoinHelper
1818
{
1919
internal static bool ProcessAsTableGroupJoin(IReadOnlyList<IJoin> tableGroupJoinables, SqlString[] withClauseFragments, bool includeAllSubclassJoins, JoinFragment joinFragment, Func<string, bool> isSubclassIncluded, ISessionFactoryImplementor sessionFactoryImplementor)
2020
{
21-
if (!NeedsTableGroupJoin(tableGroupJoinables, withClauseFragments, includeAllSubclassJoins))
21+
if (!NeedsTableGroupJoin(tableGroupJoinables, withClauseFragments, includeAllSubclassJoins, isSubclassIncluded))
2222
return false;
2323

2424
var first = tableGroupJoinables[0];
@@ -58,7 +58,7 @@ internal static bool ProcessAsTableGroupJoin(IReadOnlyList<IJoin> tableGroupJoin
5858
}
5959

6060
// detect cases when withClause is used on multiple tables or when join keys depend on subclass columns
61-
private static bool NeedsTableGroupJoin(IReadOnlyList<IJoin> joins, SqlString[] withClauseFragments, bool includeSubclasses)
61+
private static bool NeedsTableGroupJoin(IReadOnlyList<IJoin> joins, SqlString[] withClauseFragments, bool includeSubclasses, Func<string, bool> isSubclassIncluded)
6262
{
6363
bool hasWithClause = withClauseFragments.Any(x => SqlStringHelper.IsNotEmpty(x));
6464

@@ -69,7 +69,7 @@ private static bool NeedsTableGroupJoin(IReadOnlyList<IJoin> joins, SqlString[]
6969
foreach (var join in joins)
7070
{
7171
var entityPersister = GetEntityPersister(join.Joinable);
72-
if (entityPersister?.HasSubclassJoins(includeSubclasses) != true)
72+
if (entityPersister?.HasSubclassJoins(includeSubclasses && isSubclassIncluded(join.Alias)) != true)
7373
continue;
7474

7575
if (hasWithClause)

0 commit comments

Comments
 (0)