1
Vote

EFCachingCommand cache key generation bug

description

EFCachingProvider.EFCachingCommand.GetCacheKey string replace

The following code substitutes the parameter keys with the values to create a unique cache key.
foreach (DbParameter parameter in Parameters)
{
    if (parameter.Direction != ParameterDirection.Input)
    {
        // we don't cache queries with output parameters
        return null;
    }

    sb = sb.Replace("@" + parameter.ParameterName, GetLiteralValue(parameter.Value));
}
If the ParameterName (pn) is numeric and there are more then 9 (pn1,pn2,..., pn12) then pn1 value ("hello") will replace pn1 ("hello"), pn10 ("hello0"), pn11 ("hello1") and pn12 ("hello2").

This means that if I have 2 queries of 12 parameters where only the last parameter is different, they will share the same cache key.

quick fix for me because I have a simple parameter naming convention is to reverse the loop
for (int i = Parameters.Count - 1; i >= 0; i--)
{
    if (Parameters[i].Direction != ParameterDirection.Input)
    {
        // we don't cache queries with output parameters
        return null;
    }

    sb = sb.Replace("@" + Parameters[i].ParameterName, GetLiteralValue(Parameters[i].Value));
}
I realise this does not solve the underlying issue of substring replacing and assumes the parameters are sorted in ascending order.

comments