@@ -115,14 +115,14 @@ protected virtual bool IsTooManyCollections
115
115
get { return false ; }
116
116
}
117
117
118
+ //Since v5.3
119
+ [ Obsolete ( "This class is not used and will be removed in a future version." ) ]
118
120
public class DependentAlias
119
121
{
120
122
public string Alias { get ; set ; }
121
123
public string [ ] DependsOn { get ; set ; }
122
124
}
123
125
124
- readonly List < DependentAlias > _dependentAliases = new List < DependentAlias > ( ) ;
125
-
126
126
protected JoinWalker ( ISessionFactoryImplementor factory , IDictionary < string , IFilter > enabledFilters )
127
127
{
128
128
this . factory = factory ;
@@ -181,7 +181,7 @@ private void AddAssociationToJoinTree(IAssociationType type, string[] aliasedLhs
181
181
enabledFilters ,
182
182
GetSelectMode ( path ) ) ;
183
183
assoc . ValidateJoin ( path ) ;
184
- AddAssociation ( subalias , assoc ) ;
184
+ AddAssociation ( assoc ) ;
185
185
186
186
int nextDepth = currentDepth + 1 ;
187
187
@@ -204,10 +204,25 @@ protected virtual SelectMode GetSelectMode(string path)
204
204
return SelectMode . Undefined ;
205
205
}
206
206
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 )
208
223
{
209
224
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 ) ;
211
226
212
227
// add vertices
213
228
for ( int i = 0 ; i < fields . Count ; i ++ )
@@ -218,14 +233,12 @@ private static int[] GetTopologicalSortOrder(List<DependentAlias> fields)
218
233
// add edges
219
234
for ( int i = 0 ; i < fields . Count ; i ++ )
220
235
{
221
- var dependentAlias = fields [ i ] ;
222
- if ( dependentAlias . DependsOn != null )
236
+ var dependentFields = fields [ i ] . DependsOn ;
237
+ if ( dependentFields != null )
223
238
{
224
- for ( int j = 0 ; j < dependentAlias . DependsOn . Length ; j ++ )
239
+ foreach ( var dependentField in dependentFields )
225
240
{
226
- var dependentField = dependentAlias . DependsOn [ j ] ;
227
- int end ;
228
- if ( indexes . TryGetValue ( dependentField , out end ) )
241
+ if ( indexes . TryGetValue ( dependentField , out var end ) )
229
242
{
230
243
g . AddEdge ( i , end ) ;
231
244
}
@@ -236,31 +249,40 @@ private static int[] GetTopologicalSortOrder(List<DependentAlias> fields)
236
249
return g . Sort ( ) ;
237
250
}
238
251
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 )
243
253
{
244
- var dependentAlias = new DependentAlias
254
+ var dependentAliases = new List < DependentAlias2 > ( associations . Count ) ;
255
+ foreach ( var association in associations )
245
256
{
246
- Alias = subalias ,
247
- } ;
248
- _dependentAliases . Add ( dependentAlias ) ;
257
+ dependentAliases . Add ( new DependentAlias2 ( association . RHSAlias , GetDependsOn ( association ) ) ) ;
258
+ }
249
259
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 ( ) ) )
252
270
{
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 ) ;
262
276
}
263
277
278
+ return dependencies ;
279
+ }
280
+
281
+ /// <summary>
282
+ /// Adds an association
283
+ /// </summary>
284
+ private void AddAssociation ( OuterJoinableAssociation association )
285
+ {
264
286
associations . Add ( association ) ;
265
287
}
266
288
@@ -360,7 +382,7 @@ internal void AddExplicitEntityJoinAssociation(
360
382
Factory ,
361
383
enabledFilters ,
362
384
GetSelectMode ( path ) ) ;
363
- AddAssociation ( tableAlias , assoc ) ;
385
+ AddAssociation ( assoc ) ;
364
386
}
365
387
366
388
private void WalkEntityAssociationTree ( IAssociationType associationType , IOuterJoinLoadable persister ,
@@ -799,16 +821,9 @@ protected SqlString MergeOrderings(string ass, string orderBy) {
799
821
/// </summary>
800
822
protected JoinFragment MergeOuterJoins ( IList < OuterJoinableAssociation > associations )
801
823
{
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
-
810
824
JoinFragment outerjoin = Dialect . CreateOuterJoinFragment ( ) ;
811
825
826
+ var sortedAssociations = GetSortedAssociations ( associations ) ;
812
827
OuterJoinableAssociation last = null ;
813
828
foreach ( OuterJoinableAssociation oj in sortedAssociations )
814
829
{
@@ -840,6 +855,25 @@ protected JoinFragment MergeOuterJoins(IList<OuterJoinableAssociation> associati
840
855
return outerjoin ;
841
856
}
842
857
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
+
843
877
/// <summary>
844
878
/// Count the number of instances of IJoinable which are actually
845
879
/// also instances of ILoadable, or are one-to-many associations
0 commit comments