1
1
// Licensed to the .NET Foundation under one or more agreements.
2
2
// The .NET Foundation licenses this file to you under the MIT license.
3
3
4
- using System . Collections ;
5
4
using System . Collections . Concurrent ;
6
5
using Microsoft . Extensions . Caching . Memory ;
7
6
@@ -106,12 +105,21 @@ void IPrintableExpression.Print(ExpressionPrinter expressionPrinter)
106
105
private readonly struct CommandCacheKey : IEquatable < CommandCacheKey >
107
106
{
108
107
private readonly Expression _queryExpression ;
109
- private readonly IReadOnlyDictionary < string , object ? > _parameterValues ;
108
+ private readonly Dictionary < string , ParameterInfo > _parameterInfos ;
110
109
111
- public CommandCacheKey ( Expression queryExpression , IReadOnlyDictionary < string , object ? > parameterValues )
110
+ internal CommandCacheKey ( Expression queryExpression , IReadOnlyDictionary < string , object ? > parameterValues )
112
111
{
113
112
_queryExpression = queryExpression ;
114
- _parameterValues = parameterValues ;
113
+ _parameterInfos = new Dictionary < string , ParameterInfo > ( ) ;
114
+
115
+ foreach ( var ( key , value ) in parameterValues )
116
+ {
117
+ _parameterInfos [ key ] = new ParameterInfo
118
+ {
119
+ IsNull = value is null ,
120
+ ObjectArrayLength = value is object [ ] arr ? arr . Length : null
121
+ } ;
122
+ }
115
123
}
116
124
117
125
public override bool Equals ( object ? obj )
@@ -126,27 +134,18 @@ public bool Equals(CommandCacheKey commandCacheKey)
126
134
return false ;
127
135
}
128
136
129
- if ( _parameterValues . Count > 0 )
137
+ Check . DebugAssert (
138
+ _parameterInfos . Count == commandCacheKey . _parameterInfos . Count ,
139
+ "Parameter Count mismatch between identical queries" ) ;
140
+
141
+ if ( _parameterInfos . Count > 0 )
130
142
{
131
- foreach ( var ( key , value ) in _parameterValues )
143
+ foreach ( var ( key , info ) in _parameterInfos )
132
144
{
133
- if ( ! commandCacheKey . _parameterValues . TryGetValue ( key , out var otherValue ) )
145
+ if ( ! commandCacheKey . _parameterInfos . TryGetValue ( key , out var otherInfo ) || info != otherInfo )
134
146
{
135
147
return false ;
136
148
}
137
-
138
- // ReSharper disable once ArrangeRedundantParentheses
139
- if ( ( value == null ) != ( otherValue == null ) )
140
- {
141
- return false ;
142
- }
143
-
144
- if ( value is IEnumerable
145
- && value . GetType ( ) == typeof ( object [ ] ) )
146
- {
147
- // FromSql parameters must have the same number of elements
148
- return ( ( object [ ] ) value ) . Length == ( otherValue as object [ ] ) ? . Length ;
149
- }
150
149
}
151
150
}
152
151
@@ -156,4 +155,8 @@ public bool Equals(CommandCacheKey commandCacheKey)
156
155
public override int GetHashCode ( )
157
156
=> 0 ;
158
157
}
158
+
159
+ // Note that we keep only the null-ness of parameters (and array length for FromSql object arrays),
160
+ // and avoid referencing the actual parameter data (see #34028).
161
+ private readonly record struct ParameterInfo ( bool IsNull , int ? ObjectArrayLength ) ;
159
162
}
0 commit comments