1
1
using System ;
2
2
using System . Collections . Generic ;
3
3
using System . Linq ;
4
+ using NHibernate . Persister . Collection ;
4
5
using NHibernate . Persister . Entity ;
5
6
using NHibernate . SqlCommand ;
6
7
@@ -38,7 +39,7 @@ internal static bool ProcessAsTableGroupJoin(IReadOnlyList<IJoin> tableGroupJoin
38
39
join . Joinable . TableName ,
39
40
join . Alias ,
40
41
join . LHSColumns ,
41
- JoinHelper . GetRHSColumnNames ( join . AssociationType , sessionFactoryImplementor ) ,
42
+ join . RHSColumns ,
42
43
join . JoinType ,
43
44
SqlString . Empty ) ;
44
45
@@ -51,32 +52,37 @@ internal static bool ProcessAsTableGroupJoin(IReadOnlyList<IJoin> tableGroupJoin
51
52
join . Joinable . WhereJoinFragment ( join . Alias , innerJoin , include ) ) ;
52
53
}
53
54
54
- var withClause = GetTableGroupJoinWithClause ( withClauseFragments , first , sessionFactoryImplementor ) ;
55
+ var withClause = GetTableGroupJoinWithClause ( withClauseFragments , first ) ;
55
56
joinFragment . AddFromFragmentString ( withClause ) ;
56
57
return true ;
57
58
}
58
59
60
+ // detect cases when withClause is used on multiple tables or when join keys depend on subclass columns
59
61
private static bool NeedsTableGroupJoin ( IReadOnlyList < IJoin > joins , SqlString [ ] withClauseFragments , bool includeSubclasses )
60
62
{
61
- // If we don't have a with clause, we don't need a table group join
62
- if ( withClauseFragments . All ( x => SqlStringHelper . IsEmpty ( x ) ) )
63
- {
64
- return false ;
65
- }
63
+ bool hasWithClause = withClauseFragments . Any ( x => SqlStringHelper . IsNotEmpty ( x ) ) ;
66
64
67
- // If we only have one join, a table group join is only necessary if subclass columns are used in the with clause
68
- if ( joins . Count == 1 )
65
+ //NH Specific: No alias processing (see hibernate JoinSequence.NeedsTableGroupJoin)
66
+ if ( joins . Count > 1 && hasWithClause )
67
+ return true ;
68
+
69
+ foreach ( var join in joins )
69
70
{
70
- return joins [ 0 ] . Joinable is AbstractEntityPersister persister && persister . HasSubclassJoins ( includeSubclasses ) ;
71
- //NH Specific: No alias processing
72
- //return isSubclassAliasDereferenced( joins[ 0], withClauseFragment );
71
+ var entityPersister = GetEntityPersister ( join . Joinable ) ;
72
+ if ( entityPersister ? . HasSubclassJoins ( includeSubclasses ) != true )
73
+ continue ;
74
+
75
+ if ( hasWithClause )
76
+ return true ;
77
+
78
+ if ( entityPersister . ColumnsDependOnSubclassJoins ( join . RHSColumns ) )
79
+ return true ;
73
80
}
74
81
75
- //NH Specific: No alias processing (see hibernate JoinSequence.NeedsTableGroupJoin)
76
- return true ;
82
+ return false ;
77
83
}
78
84
79
- private static SqlString GetTableGroupJoinWithClause ( SqlString [ ] withClauseFragments , IJoin first , ISessionFactoryImplementor factory )
85
+ private static SqlString GetTableGroupJoinWithClause ( SqlString [ ] withClauseFragments , IJoin first )
80
86
{
81
87
SqlStringBuilder fromFragment = new SqlStringBuilder ( ) ;
82
88
fromFragment . Add ( ")" ) . Add ( " on " ) ;
@@ -85,12 +91,18 @@ private static SqlString GetTableGroupJoinWithClause(SqlString[] withClauseFragm
85
91
var isAssociationJoin = lhsColumns . Length > 0 ;
86
92
if ( isAssociationJoin )
87
93
{
94
+ var entityPersister = GetEntityPersister ( first . Joinable ) ;
88
95
string rhsAlias = first . Alias ;
89
- string [ ] rhsColumns = JoinHelper . GetRHSColumnNames ( first . AssociationType , factory ) ;
90
- fromFragment . Add ( lhsColumns [ 0 ] ) . Add ( "=" ) . Add ( rhsAlias ) . Add ( "." ) . Add ( rhsColumns [ 0 ] ) ;
91
- for ( int j = 1 ; j < lhsColumns . Length ; j ++ )
96
+ string [ ] rhsColumns = first . RHSColumns ;
97
+ for ( int j = 0 ; j < lhsColumns . Length ; j ++ )
92
98
{
93
- fromFragment . Add ( " and " ) . Add ( lhsColumns [ j ] ) . Add ( "=" ) . Add ( rhsAlias ) . Add ( "." ) . Add ( rhsColumns [ j ] ) ;
99
+ fromFragment . Add ( lhsColumns [ j ] )
100
+ . Add ( "=" )
101
+ . Add ( entityPersister ? . GenerateTableAliasForColumn ( rhsAlias , rhsColumns [ j ] ) ?? rhsAlias )
102
+ . Add ( "." )
103
+ . Add ( rhsColumns [ j ] ) ;
104
+ if ( j != lhsColumns . Length - 1 )
105
+ fromFragment . Add ( " and " ) ;
94
106
}
95
107
}
96
108
@@ -99,6 +111,15 @@ private static SqlString GetTableGroupJoinWithClause(SqlString[] withClauseFragm
99
111
return fromFragment . ToSqlString ( ) ;
100
112
}
101
113
114
+ private static AbstractEntityPersister GetEntityPersister ( IJoinable joinable )
115
+ {
116
+ if ( ! joinable . IsCollection )
117
+ return joinable as AbstractEntityPersister ;
118
+
119
+ var collection = ( IQueryableCollection ) joinable ;
120
+ return collection . ElementType . IsEntityType ? collection . ElementPersister as AbstractEntityPersister : null ;
121
+ }
122
+
102
123
private static void AppendWithClause ( SqlStringBuilder fromFragment , bool hasConditions , SqlString [ ] withClauseFragments )
103
124
{
104
125
for ( var i = 0 ; i < withClauseFragments . Length ; i ++ )
0 commit comments