老习惯还是先把GetCachedParameters这个函数的代码贴出来。
SqlParameter[] cachedParms = (SqlParameter[])parmCache[cacheKey];
if (cachedParms == null)
return null;
SqlParameter[] clonedParms = new SqlParameter[cachedParms.Length];
for (int i = 0, j = cachedParms.Length; i < j; i++)
clonedParms[i] = (SqlParameter)((ICloneable)cachedParms[i]).Clone();
return clonedParms;
}
这里涉及到了一个哈希表hastTable定义了parmCache来存储缓存的。那它到底是怎样的一种机制呢?我自己认真的分析了下代码,
GetCachedParameters这个函数是它缓存都是空的也就是说return null。就拿库存Inventory来说吧,得到parm空后
就只能自己new Sqlparmeter了,显然这样比较耗内存。还是看下Invertory此时是怎样new Sqlparmeter吧:
2 SqlParameter[] parms = SqlHelper.GetCachedParameters(SQL_TAKE_INVENTORY + i);
3
4 if (parms ==null) {
5 parms =new SqlParameter[] {
6 new SqlParameter("@Quantity"+ i, SqlDbType.Int),
7 new SqlParameter("@ItemId"+i, SqlDbType.VarChar, 10)};
8
9 SqlHelper.CacheParameters(SQL_TAKE_INVENTORY + i, parms);
10 }
11
12 return parms;
13 }
从第四行开始就是第一次更新要新建缓存的代码了。之前我一直在想,为什么Invertory中的TakeStock函数更新时是这样找缓存的:
SqlParameter[] inventoryParms;
foreach (LineItemInfo item in items) {
inventoryParms = GetInventoryParameters(i);
i++;
}
而这个GetInventoryParameters(i)调用SqlHelper.GetCachedParameters(SQL_TAKE_INVENTORY + i)是明显有加了一句
SQL_TAKE_INVENTORY了。这是为什么呢?我猜想SQL_TAKE_INVENTORY+i这又意义吗?
后来想想还是觉得这样做的好处是可以在hastTable中唯一标识一个Key吧,hastTable只能通过这个key来查找缓存。
但是问题又来呢。在SQLHelper.GetCachedParameters传递parameter参数的时候为什么好克隆一个parameter参数呢?
网上有人这样解释:
1、为什么要使用Clone方法返回SqlParameter[],作用是什么?
==========防止你调用后改变缓存中存在的参数。
2、直接返还就是引用,克隆返还的对象--操作内存,不同的调用者给不同的值。
这接调用怎么会改变缓存中的参数呢?缓存中的参数不是已经在hastTable中了吗?我们每次调用的时候不是都有唯一的标识吗?
这样怎么会改变缓存中的参数?我不理解。