@@ -115,14 +115,14 @@ protected virtual bool IsTooManyCollections
115115 get { return false ; }
116116 }
117117
118+ //Since v5.3
119+ [ Obsolete ( "This class is not used and will be removed in a future version." ) ]
118120 public class DependentAlias
119121 {
120122 public string Alias { get ; set ; }
121123 public string [ ] DependsOn { get ; set ; }
122124 }
123125
124- readonly List < DependentAlias > _dependentAliases = new List < DependentAlias > ( ) ;
125-
126126 protected JoinWalker ( ISessionFactoryImplementor factory , IDictionary < string , IFilter > enabledFilters )
127127 {
128128 this . factory = factory ;
@@ -181,7 +181,7 @@ private void AddAssociationToJoinTree(IAssociationType type, string[] aliasedLhs
181181 enabledFilters ,
182182 GetSelectMode ( path ) ) ;
183183 assoc . ValidateJoin ( path ) ;
184- AddAssociation ( subalias , assoc ) ;
184+ AddAssociation ( assoc ) ;
185185
186186 int nextDepth = currentDepth + 1 ;
187187
@@ -204,10 +204,25 @@ protected virtual SelectMode GetSelectMode(string path)
204204 return SelectMode . Undefined ;
205205 }
206206
207- private static int [ ] GetTopologicalSortOrder ( List < DependentAlias > fields )
207+ private struct DependentAlias2
208+ {
209+ public DependentAlias2 ( string alias , ICollection < string > dependsOn )
210+ {
211+ Alias = alias ;
212+ DependsOn = dependsOn ;
213+ }
214+
215+ public string Alias { get ; }
216+ public ICollection < string > DependsOn { get ; }
217+ }
218+
219+ /// <summary>
220+ /// Returns list of indexes in sorted order
221+ /// </summary>
222+ private static int [ ] GetTopologicalSortOrder ( IList < DependentAlias2 > fields )
208223 {
209224 TopologicalSorter g = new TopologicalSorter ( fields . Count ) ;
210- Dictionary < string , int > indexes = new Dictionary < string , int > ( StringComparer . OrdinalIgnoreCase ) ;
225+ Dictionary < string , int > indexes = new Dictionary < string , int > ( fields . Count , StringComparer . OrdinalIgnoreCase ) ;
211226
212227 // add vertices
213228 for ( int i = 0 ; i < fields . Count ; i ++ )
@@ -218,14 +233,12 @@ private static int[] GetTopologicalSortOrder(List<DependentAlias> fields)
218233 // add edges
219234 for ( int i = 0 ; i < fields . Count ; i ++ )
220235 {
221- var dependentAlias = fields [ i ] ;
222- if ( dependentAlias . DependsOn != null )
236+ var dependentFields = fields [ i ] . DependsOn ;
237+ if ( dependentFields != null )
223238 {
224- for ( int j = 0 ; j < dependentAlias . DependsOn . Length ; j ++ )
239+ foreach ( var dependentField in dependentFields )
225240 {
226- var dependentField = dependentAlias . DependsOn [ j ] ;
227- int end ;
228- if ( indexes . TryGetValue ( dependentField , out end ) )
241+ if ( indexes . TryGetValue ( dependentField , out var end ) )
229242 {
230243 g . AddEdge ( i , end ) ;
231244 }
@@ -236,31 +249,40 @@ private static int[] GetTopologicalSortOrder(List<DependentAlias> fields)
236249 return g . Sort ( ) ;
237250 }
238251
239- /// <summary>
240- /// Adds an association and extracts the aliases the association's 'with clause' is dependent on
241- /// </summary>
242- private void AddAssociation ( string subalias , OuterJoinableAssociation association )
252+ private static List < DependentAlias2 > GetDependentAliases ( IList < OuterJoinableAssociation > associations )
243253 {
244- var dependentAlias = new DependentAlias
254+ var dependentAliases = new List < DependentAlias2 > ( associations . Count ) ;
255+ foreach ( var association in associations )
245256 {
246- Alias = subalias ,
247- } ;
248- _dependentAliases . Add ( dependentAlias ) ;
257+ dependentAliases . Add ( new DependentAlias2 ( association . RHSAlias , GetDependsOn ( association ) ) ) ;
258+ }
249259
250- var on = association . On . ToString ( ) ;
251- if ( ! string . IsNullOrEmpty ( on ) )
260+ return dependentAliases ;
261+ }
262+
263+ private static HashSet < string > GetDependsOn ( OuterJoinableAssociation association )
264+ {
265+ if ( SqlStringHelper . IsEmpty ( association . On ) )
266+ return null ;
267+
268+ var dependencies = new HashSet < string > ( StringComparer . OrdinalIgnoreCase ) ;
269+ foreach ( Match match in aliasRegex . Matches ( association . On . ToString ( ) ) )
252270 {
253- var dependencies = new HashSet < string > ( StringComparer . OrdinalIgnoreCase ) ;
254- foreach ( Match match in aliasRegex . Matches ( on ) )
255- {
256- string alias = match . Value ;
257- if ( string . Equals ( alias , subalias , StringComparison . OrdinalIgnoreCase ) )
258- continue ;
259- dependencies . Add ( alias ) ;
260- }
261- dependentAlias . DependsOn = dependencies . ToArray ( ) ;
271+ string alias = match . Value ;
272+ if ( string . Equals ( alias , association . RHSAlias , StringComparison . OrdinalIgnoreCase ) )
273+ continue ;
274+
275+ dependencies . Add ( alias ) ;
262276 }
263277
278+ return dependencies ;
279+ }
280+
281+ /// <summary>
282+ /// Adds an association
283+ /// </summary>
284+ private void AddAssociation ( OuterJoinableAssociation association )
285+ {
264286 associations . Add ( association ) ;
265287 }
266288
@@ -360,7 +382,7 @@ internal void AddExplicitEntityJoinAssociation(
360382 Factory ,
361383 enabledFilters ,
362384 GetSelectMode ( path ) ) ;
363- AddAssociation ( tableAlias , assoc ) ;
385+ AddAssociation ( assoc ) ;
364386 }
365387
366388 private void WalkEntityAssociationTree ( IAssociationType associationType , IOuterJoinLoadable persister ,
@@ -799,16 +821,9 @@ protected SqlString MergeOrderings(string ass, string orderBy) {
799821 /// </summary>
800822 protected JoinFragment MergeOuterJoins ( IList < OuterJoinableAssociation > associations )
801823 {
802- IList < OuterJoinableAssociation > sortedAssociations = new List < OuterJoinableAssociation > ( ) ;
803-
804- var indices = GetTopologicalSortOrder ( _dependentAliases ) ;
805- for ( int index = indices . Length - 1 ; index >= 0 ; index -- )
806- {
807- sortedAssociations . Add ( associations [ indices [ index ] ] ) ;
808- }
809-
810824 JoinFragment outerjoin = Dialect . CreateOuterJoinFragment ( ) ;
811825
826+ var sortedAssociations = GetSortedAssociations ( associations ) ;
812827 OuterJoinableAssociation last = null ;
813828 foreach ( OuterJoinableAssociation oj in sortedAssociations )
814829 {
@@ -840,6 +855,25 @@ protected JoinFragment MergeOuterJoins(IList<OuterJoinableAssociation> associati
840855 return outerjoin ;
841856 }
842857
858+ private static IList < OuterJoinableAssociation > GetSortedAssociations ( IList < OuterJoinableAssociation > associations )
859+ {
860+ if ( associations . Count < 2 )
861+ return associations ;
862+
863+ var fields = GetDependentAliases ( associations ) ;
864+ if ( ! fields . Exists ( a => a . DependsOn ? . Count > 0 ) )
865+ return associations ;
866+
867+ var indexes = GetTopologicalSortOrder ( fields ) ;
868+ var sortedAssociations = new List < OuterJoinableAssociation > ( associations . Count ) ;
869+ for ( int index = indexes . Length - 1 ; index >= 0 ; index -- )
870+ {
871+ sortedAssociations . Add ( associations [ indexes [ index ] ] ) ;
872+ }
873+
874+ return sortedAssociations ;
875+ }
876+
843877 /// <summary>
844878 /// Count the number of instances of IJoinable which are actually
845879 /// also instances of ILoadable, or are one-to-many associations
0 commit comments