11// Licensed to the .NET Foundation under one or more agreements.
22// The .NET Foundation licenses this file to you under the MIT license.
33
4- using System . Collections ;
54using System . Collections . Concurrent ;
65using Microsoft . Extensions . Caching . Memory ;
76
@@ -106,12 +105,21 @@ void IPrintableExpression.Print(ExpressionPrinter expressionPrinter)
106105 private readonly struct CommandCacheKey : IEquatable < CommandCacheKey >
107106 {
108107 private readonly Expression _queryExpression ;
109- private readonly IReadOnlyDictionary < string , object ? > _parameterValues ;
108+ private readonly Dictionary < string , ParameterInfo > _parameterInfos ;
110109
111- public CommandCacheKey ( Expression queryExpression , IReadOnlyDictionary < string , object ? > parameterValues )
110+ internal CommandCacheKey ( Expression queryExpression , IReadOnlyDictionary < string , object ? > parameterValues )
112111 {
113112 _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+ }
115123 }
116124
117125 public override bool Equals ( object ? obj )
@@ -126,27 +134,18 @@ public bool Equals(CommandCacheKey commandCacheKey)
126134 return false ;
127135 }
128136
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 )
130142 {
131- foreach ( var ( key , value ) in _parameterValues )
143+ foreach ( var ( key , info ) in _parameterInfos )
132144 {
133- if ( ! commandCacheKey . _parameterValues . TryGetValue ( key , out var otherValue ) )
145+ if ( ! commandCacheKey . _parameterInfos . TryGetValue ( key , out var otherInfo ) || info != otherInfo )
134146 {
135147 return false ;
136148 }
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- }
150149 }
151150 }
152151
@@ -156,4 +155,8 @@ public bool Equals(CommandCacheKey commandCacheKey)
156155 public override int GetHashCode ( )
157156 => 0 ;
158157 }
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 ) ;
159162}
0 commit comments