@@ -20,10 +20,8 @@ public abstract class SubqueryExpression : AbstractCriterion
2020private QueryParameters parameters ;
2121private IType [ ] types ;
2222
23- [ NonSerialized ] private CriteriaQueryTranslator innerQuery ;
24-
2523protected SubqueryExpression ( String op , String quantifier , DetachedCriteria dc )
26- : this ( op , quantifier , dc , true )
24+ : this ( op , quantifier , dc , true )
2725{
2826}
2927
@@ -44,16 +42,23 @@ public IType[] GetTypes()
4442
4543public override SqlString ToSqlString ( ICriteria criteria , ICriteriaQuery criteriaQuery , IDictionary < string , IFilter > enabledFilters )
4644{
47- InitializeInnerQueryAndParameters ( criteriaQuery ) ;
45+ ISessionFactoryImplementor factory = criteriaQuery . Factory ;
46+
47+ var innerQuery = new CriteriaQueryTranslator (
48+ factory ,
49+ criteriaImpl , //implicit polymorphism not supported (would need a union)
50+ criteriaImpl . EntityOrClassName ,
51+ criteriaQuery . GenerateSQLAlias ( ) ,
52+ criteriaQuery ) ;
53+
54+ types = innerQuery . HasProjection ? innerQuery . ProjectedTypes : null ;
4855
4956if ( innerQuery . HasProjection == false )
5057{
5158throw new QueryException ( "Cannot use subqueries on a criteria without a projection." ) ;
5259}
5360
54- ISessionFactoryImplementor factory = criteriaQuery . Factory ;
55-
56- IOuterJoinLoadable persister = ( IOuterJoinLoadable ) factory . GetEntityPersister ( criteriaImpl . EntityOrClassName ) ;
61+ IOuterJoinLoadable persister = ( IOuterJoinLoadable ) factory . GetEntityPersister ( criteriaImpl . EntityOrClassName ) ;
5762
5863//patch to generate joins on subqueries
5964//stolen from CriteriaLoader
@@ -73,11 +78,6 @@ public override SqlString ToSqlString(ICriteria criteria, ICriteriaQuery criteri
7378sql = factory . Dialect . GetLimitString ( sql , offset , limit , offsetParameter , limitParameter ) ;
7479}
7580
76- // during CriteriaImpl.Clone we are doing a shallow copy of each criterion.
77- // this is not a problem for common criterion but not for SubqueryExpression because here we are holding the state of inner CriteriaTraslator (ICriteriaQuery).
78- // After execution (ToSqlString) we have to clean the internal state because the next execution may be performed in a different tree reusing the same istance of SubqueryExpression.
79- innerQuery = null ;
80-
8181SqlStringBuilder buf = new SqlStringBuilder ( ) . Add ( ToLeftSqlString ( criteria , criteriaQuery ) ) ;
8282if ( op != null )
8383{
@@ -88,7 +88,7 @@ public override SqlString ToSqlString(ICriteria criteria, ICriteriaQuery criteri
8888{
8989buf . Add ( quantifier ) . Add ( " " ) ;
9090}
91-
91+
9292buf . Add ( "(" ) . Add ( sql ) . Add ( ")" ) ;
9393
9494if ( quantifier != null && prefixOp == false )
@@ -101,9 +101,9 @@ public override SqlString ToSqlString(ICriteria criteria, ICriteriaQuery criteri
101101
102102public override string ToString ( )
103103{
104- if ( prefixOp )
104+ if ( prefixOp )
105105return string . Format ( "{0} {1} ({2})" , op , quantifier , criteriaImpl ) ;
106-
106+
107107return string . Format ( "{0} ({1}) {2}" , op , criteriaImpl , quantifier ) ;
108108}
109109
@@ -117,23 +117,6 @@ public override IProjection[] GetProjections()
117117return null ;
118118}
119119
120- public void InitializeInnerQueryAndParameters ( ICriteriaQuery criteriaQuery )
121- {
122- if ( innerQuery == null )
123- {
124- ISessionFactoryImplementor factory = criteriaQuery . Factory ;
125-
126- innerQuery = new CriteriaQueryTranslator (
127- factory ,
128- criteriaImpl , //implicit polymorphism not supported (would need a union)
129- criteriaImpl . EntityOrClassName ,
130- criteriaQuery . GenerateSQLAlias ( ) ,
131- criteriaQuery ) ;
132-
133- types = innerQuery . HasProjection ? innerQuery . ProjectedTypes : null ;
134- }
135- }
136-
137120public ICriteria Criteria
138121{
139122// NH-1146
0 commit comments