@@ -23,14 +23,13 @@ public class QueryKey : IDeserializationCallback
23
23
private readonly int _maxRows = RowSelection . NoValue ;
24
24
25
25
// Sets and dictionaries are populated last during deserialization, causing them to be potentially empty
26
- // during the deserialization callback. This causes them to be unreliable when used in hashcode computations.
27
- // So better also serialize them as other structures and use those other structures in hashcode computation.
28
- // We nonetheless need to also serialize them, because they are externally supplied and may use a custom
29
- // comparer, implementation, ...
30
- private readonly IDictionary < string , TypedValue > _namedParameters ;
31
- private readonly ISet < FilterKey > _filters ;
32
- private IEnumerable < KeyValuePair < string , TypedValue > > _serializedNamedParameters ;
33
- private IEnumerable < FilterKey > _serializedFilters ;
26
+ // during the deserialization callback. This causes them to be unreliable when used in hashcode or equals
27
+ // computations. These computations occur during the deserialization callback for example when another
28
+ // serialized set or dictionary contain an instance of this class.
29
+ // So better serialize them as other structures, so long for Equals implementation which actually needs a
30
+ // dictionary and set.
31
+ private readonly KeyValuePair < string , TypedValue > [ ] _namedParameters ;
32
+ private readonly FilterKey [ ] _filters ;
34
33
35
34
private readonly CacheableResultTransformer _customTransformer ;
36
35
// hashcode may vary among processes, they cannot be stored and have to be re-computed after deserialization
@@ -67,8 +66,9 @@ public QueryKey(ISessionFactoryImplementor factory, SqlString queryString, Query
67
66
_firstRow = RowSelection . NoValue ;
68
67
_maxRows = RowSelection . NoValue ;
69
68
}
70
- _namedParameters = queryParameters . NamedParameters ;
71
- _filters = filters ;
69
+
70
+ _namedParameters = queryParameters . NamedParameters ? . ToArray ( ) ;
71
+ _filters = filters ? . ToArray ( ) ;
72
72
_customTransformer = customTransformer ;
73
73
74
74
_hashCode = ComputeHashCode ( ) ;
@@ -140,35 +140,14 @@ public override bool Equals(object other)
140
140
}
141
141
}
142
142
143
- // On deserialization, _namedParameters and _filters may be not yet populated. Use their _serialization
144
- // counterparts if they are defined.
145
- if ( _serializedFilters != null || that . _serializedFilters != null )
146
- {
147
- var filters = _serializedFilters ?? _filters ;
148
- var thatFilters = that . _serializedFilters ?? that . _filters ;
149
- // BagEquals is less efficient than a SetEquals, but if the sets are using a custom comparer, it
150
- // will cause less issues than rebuilding sets without the custom comparer.
151
- if ( ! CollectionHelper . BagEquals ( filters , thatFilters ) )
152
- return false ;
153
- }
154
- else if ( ! CollectionHelper . SetEquals ( _filters , that . _filters ) )
155
- {
143
+ // BagEquals is less efficient than a SetEquals or DictionaryEquals, but serializing dictionaries causes
144
+ // issues on deserialization if GetHashCode or Equals are called in its deserialization callback. And
145
+ // building sets or dictionaries on the fly will in most cases be worst than BagEquals, unless re-coding
146
+ // its short-circuits.
147
+ if ( ! CollectionHelper . BagEquals ( _filters , that . _filters ) )
156
148
return false ;
157
- }
158
-
159
- if ( _serializedNamedParameters != null || that . _serializedNamedParameters != null )
160
- {
161
- var namedParameters = _serializedNamedParameters ?? _namedParameters ;
162
- var thatNamedParameters = that . _serializedNamedParameters ?? that . _namedParameters ;
163
- // BagEquals is less efficient than a DictionaryEquals, but if the dictionaries are using a custom
164
- // comparer, it will cause less issues than rebuilding the dictionaries without the custom comparer.
165
- if ( ! CollectionHelper . BagEquals ( namedParameters , thatNamedParameters , NamedParameterComparer . Instance ) )
166
- return false ;
167
- }
168
- else if ( ! CollectionHelper . DictionaryEquals ( _namedParameters , that . _namedParameters ) )
169
- {
149
+ if ( ! CollectionHelper . BagEquals ( _namedParameters , that . _namedParameters , NamedParameterComparer . Instance ) )
170
150
return false ;
171
- }
172
151
173
152
if ( ! CollectionHelper . SequenceEquals < int > ( _multiQueriesFirstRows , that . _multiQueriesFirstRows ) )
174
153
{
@@ -194,16 +173,6 @@ public override int GetHashCode()
194
173
public void OnDeserialization ( object sender )
195
174
{
196
175
_hashCode = ComputeHashCode ( ) ;
197
-
198
- _serializedNamedParameters = null ;
199
- _serializedFilters = null ;
200
- }
201
-
202
- [ OnSerializing ]
203
- private void OnSerializing ( StreamingContext context )
204
- {
205
- _serializedNamedParameters = _namedParameters ? . ToArray ( ) ;
206
- _serializedFilters = _filters ? . ToArray ( ) ;
207
176
}
208
177
209
178
public int ComputeHashCode ( )
@@ -214,10 +183,9 @@ public int ComputeHashCode()
214
183
result = 37 * result + _firstRow . GetHashCode ( ) ;
215
184
result = 37 * result + _maxRows . GetHashCode ( ) ;
216
185
217
- // On deserialization, _namedParameters may be not yet populated. Use _serializedNamedParameters
218
- // if it is defined.
219
- var namedParameters = _serializedNamedParameters ?? _namedParameters ;
220
- result = 37 * result + ( namedParameters == null ? 0 : CollectionHelper . GetHashCode ( namedParameters , NamedParameterComparer . Instance ) ) ;
186
+ result = 37 * result + ( _namedParameters == null
187
+ ? 0
188
+ : CollectionHelper . GetHashCode ( _namedParameters , NamedParameterComparer . Instance ) ) ;
221
189
222
190
for ( int i = 0 ; i < _types . Length ; i ++ )
223
191
{
@@ -244,12 +212,9 @@ public int ComputeHashCode()
244
212
}
245
213
}
246
214
247
- // On deserialization, _filters may be not yet populated. Use _serializedFilters
248
- // if it is defined.
249
- var filters = _serializedFilters ?? _filters ;
250
- if ( filters != null )
215
+ if ( _filters != null )
251
216
{
252
- result = 37 * result + CollectionHelper . GetHashCode ( filters ) ;
217
+ result = 37 * result + CollectionHelper . GetHashCode ( _filters ) ;
253
218
}
254
219
255
220
result = 37 * result + ( _customTransformer == null ? 0 : _customTransformer . GetHashCode ( ) ) ;
0 commit comments