zoukankan      html  css  js  c++  java
  • 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,方便了点

  • 相关阅读:
    [读书笔记]黑客与画家[Hackers.and.Painters]
    android电池充电以及电量检测驱动分析
    LV在系统重启后不能自动激活(boot.lvm&after.loca)
    线段树菜鸟一题+归并排序【求逆序数】POJ2299
    【PAT】1035. Password (20)
    Android应用开发学习笔记之ContentProvider
    UVAlive 2322 Wooden Sticks(贪心)
    卸载QTP
    线段树模板
    2013 CSU校队选拔赛(1) 部分题解
  • 原文地址:https://www.cnblogs.com/huaizuo/p/2100282.html
Copyright © 2011-2022 走看看