Invertory类对商品库存的更新困惑解决了

Invertory类对商品库存的更新,应该是涉及到数据库MSPetShop4和数据库MSPetShop4Orders。

因为MSPetShop4.Inventory的数量要更改要扣除MSPetShop4Orders.LineItem的订单数量。

如果是我来处理的话应该会这样做:
update Invertory set Qty=Qty-@Quentity where ItemId=@ItemId;
就差俩个参数@Quentity 和@ItemId,然后就借助SQLHelper的带参函数处处理就可以了。

但PetShop.SQLServer.Iventory不是这样处理的,来看看它是怎样处理的吧:

View Code
1 publicvoid TakeStock(LineItemInfo[] items) {
2
3 SqlParameter[] inventoryParms;
4 SqlCommand cmd =new SqlCommand();
5
6 //Open a connection
7  using (SqlConnection conn =new SqlConnection(SqlHelper.ConnectionStringInventoryDistributedTransaction)) {
8
9 StringBuilder strSQL =new StringBuilder();
10 int i =0;
11
12 //Append a statement to the batch for each item in the array
13  foreach (LineItemInfo item in items) {
14
15 strSQL.Append(SQL_TAKE_INVENTORY);
16
17 inventoryParms = GetInventoryParameters(i);
18
19 strSQL.Append("@Quantity").Append(i).Append(" WHERE ItemId = @ItemId").Append(i).Append(";");
20
21 //Bind parameters
22   inventoryParms[0].Value = item.Quantity;
23 inventoryParms[1].Value = item.ItemId;
24
25 foreach (SqlParameter parm in inventoryParms)
26 cmd.Parameters.Add(parm);
27 i++;
28 }
29
30 // Open the connection
31   conn.Open();
32
33 //Set up the command
34  
35 cmd.Connection = conn;
36 cmd.CommandType = CommandType.Text;
37 cmd.CommandText = strSQL.ToString();
38
39 //Execute the query
40   cmd.ExecuteNonQuery();
41 cmd.Parameters.Clear();
42
43 }
44 }
privatestatic SqlParameter[] GetInventoryParameters(int i) {
SqlParameter[] parms
= SqlHelper.GetCachedParameters(SQL_TAKE_INVENTORY + i);

if (parms ==null) {
parms
=new SqlParameter[] {
new SqlParameter("@Quantity"+ i, SqlDbType.Int),
new SqlParameter("@ItemId"+i, SqlDbType.VarChar, 10)};

SqlHelper.CacheParameters(SQL_TAKE_INVENTORY
+ i, parms);
}

return parms;
}

我困惑的地方就是它干嘛要再调用GetInventoryParameteres函数?为什么不直接在TackStock函数里面添加

parms =new SqlParameter[] {
new SqlParameter("@Quantity"+ i, SqlDbType.Int),
new SqlParameter("@ItemId"+i, SqlDbType.VarChar, 10)
};

这样岂不更方便?

也许它这样做事有性能优化的作用吧,来看看它这样做到底多做了些什么吧:

GetInventoryParameters函数调用了SQLHelper里的GetCachedParameters函数,这个函数是这样的:

publicstatic SqlParameter[] GetCachedParameters(string cacheKey) {
SqlParameter[] cachedParms
= (SqlParameter[])parmCache[cacheKey];

if (cachedParms ==null)
returnnull;

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;
}

其中parmCache是SQLHelper的一个静态成员,具体是:

privatestatic Hashtable parmCache = Hashtable.Synchronized(new Hashtable());

来分析下SQLHelper.GetCachedParameters函数吧,按字面理解这个函数是想得到缓存中的cmdParm了,

但它们传过来的“UPDATE Inventory SET Qty = Qty -”+ i,是没有command的参数呀,所以最终传回去的知识null了。

所以就觉得这样处理是不是多余了。不知道自己是否理解错误了,但先写下来吧,以后懂了再改吧。

但即使他们这样处理很好,我还是有点不明白,那就是,传到SQLServer.GetCachedParameters的string语句是怎么读取去参数的,

参照上面。SqlParameter[] cachedParms = (SqlParameter[])parmCache[cacheKey];这句话要怎么理解?

问题好像解决了,今天看到博客园有个人这样解释的:

CacheParameter是将一个SqlCommand对应的SqlParameter对象缓存起来,GetCachedParameters自然就是取出SqlCommand需要的SqlParameter对象了

这样做的作用有:

1.SqlParameter的new过程似乎蛮占资源的,因此缓存减少了new的次数,提高了效率

2.每一次都对一个SqlCommand写n次的cmd.Parameters.Add(xxx)很麻烦,而GetCachedParameters可以直接取出来所有的SqlParameter,方便了点

原文地址:https://www.cnblogs.com/huaizuo/p/2100282.html