• 记一次代码重构


          前段时间,我负责一款APP的接口开发,其中有一个新增的操作,逻辑比较复杂,涉及到9个数据表的数据改动,而且表又跨库,这9个表呢,个别在别处还有单表操作,所以为了复用之前的数据层,笔者直接想到了使用分布式事务TransactionScope,在业务层直接调用多个DAO类的方法。

            再说下这个新增操作吧,这个APP是用来回收某产品的,所以这个新增操作是创建一个二手产品的订单,首页是五个项目,如图(下图中各具体项只是为说明数据结构),
             
            资料从左向右填写,每次填完信息暂存在本地,点创建回收订单,信息提交到后台接口,其中【产品信息】下的配置信息和【产品描述】【图片信息】的全部信息采用配置字典表分别存储,产品描述关联到订单,而配置信息和图片则关联到产品。全部本地信息以JSON格式提交,格式如下
    {
        "data": {
      "customer": {
               
                "CustomerName": "Ikki里",
                "Mobile": "13988888888",
     "Address": " "
            },
     "product": {
                "Name": "",
                "CPU": "",
                "Color": 0
            },
            "productCI": [
                "1,2",
                "2,1",
                "3,0"
     
            ],
            "productCheck": [
                "227,",
                "231,A+"
            ],
            "productPic": [
                {
                    "ViewUrl": "http://imageup.xxxx.com/xxxxx/09/03/85b9213e-7bf3-4312-b59f-276ea0f9ac70_901.png",
                    "ImgText": "左前",
                    "PicPath": "/xxxx/09/03/85b9213e-7bf3-4312-b59f-276ea0f9ac70_{0}.png",
                    "DictID": 349
                }
            ],
            "productPrice": {
                "PriceMax": "66.0",
                "PriceMin": "1.0",
                "Note": "abc",
            },
           
          
        }
    }
           一切进行得还算顺利,但当把程序部署到正式环境时,问题出现了,提示分布式事务未被初始化之类的错误,具体想不起来了,尝试了网上的一些解决方法,比如本地DTC的一些设置,但都无效果,最后只好放弃了,又想到两个解决方案,第一,在DAO层中重写一个大的方法,包含全部的数据操作方法,在DAO类中DbTransaction 事务;第二,使用存储过程,但想到要给存储过程传这么多参数进去,我还是放弃了。好吧,就按第一种解决思路来。
            重构的定义是在不改变系统的外部功能的前提下,只对内部的结构进行重新的整理,换到我现在的环境就是APP已经开发测试完成,所以我的接口的任何改变都不应该让APP感觉到我的变化,接下来我做的事就是对现在的代码重构,顿时觉得自己做一件很高大上的事,哈哈。
           先说下之前的操作方法吧,代码太多了,我就简单示例下    
      private string Add(HttpContext context)
            {
                string result = string.Empty;
                using (System.Transactions.TransactionScope scope = new System.Transactions.TransactionScope())
                {
                    #region 1、客户资料
                    CustomerDao.Add();
                         or  CustomerDao.Update  ();
                    #endregion
                    #region 2、产品信息,
                    ProductDao.Add();
                         or  ProductDao.Update  ();
                    #endregion                
                    #region 4、图片信息
                    PicDao.Add();
                         or   PicDao.Update  ();
                    #endregion
                    #region  5、回收价格
                    PriceDao.Add();
                         or PriceDao.Update  ();
                    #endregion
                    #region 3、产品描述信息
                    ProductDesDao.Add();
                        or ProductDesDao.Update  ();
                    #endregion
                    scope.Complete();
                    result = ERP.Common.Json.JsonHelper.ReturnJson(1, "保存成功!");
                }
                return result;
            }

            难道真的要把每个DAO下的方法复制粘贴出来,然后拼SQL,对参数?简直难以想像,那样还意味着以后要维护两套DAO方法,并且是同一功能。关键是明天早上是必须要交付给客户的,现在已经晚上快10点了...

            终于想到一个比较靠谱,又敏捷的方法,为了保险,我新建一个类,专门用来组织SQL和参数,把原来的DAO方法复制到这个类中,然后不执行SQL,而是用一个字典返回SQL+参数,这样在上层调用接收到这个字典,用字典的原因是由于每个DAO方法的参数类型不同,这样方便接收。把所有5个要执行的操作都接收完成后,再写一个总的保存方法,这个方法里可以用IDbTransaction事务来保证安全。原来的单个表操作的方法也可以直接用这样的方式来调用保存,不受影响,最重要的是APP端不用做任务的改动。
          总的保存方法如下:
      1  public ResultModel SaveAll(Dictionary<string, object> dicParam)
      2         {
      3             ResultModel ret = new ResultModel();
      4             ret.Status = 0;
      5             ret.Message = "";
      6             lock (padlock)
      7             {
      8                 IDbTransaction trans = null;
      9                 try
     10                 {
     11                     using (var conn = new SqlConnection(DbConnString))
     12                     {
     13                         conn.Open();
     14                         trans = conn.BeginTransaction();
     15                         Dictionary<string, object> _param = new Dictionary<string, object>();
     16                         var sql = string.Empty;
     17                         var countSql = string.Empty;
     18                         var delSql = string.Empty;
     19                         //1、客户资料
     20                         int sellerId = 0;
     21                         _param = (Dictionary<string, object>)dicParam["sellerCarInfo"];
     22                         SellerCarInfoModel sellerModel = (SellerCarInfoModel)_param["model"];
     23                         sql = _param["sql"].ToString();                       
     24                         if (sellerModel.ID > 0)
     25                         {
     26                             conn.Execute(sql.ToString(), sellerModel, trans);
     27                             sellerId = sellerModel.ID;
     28                         }
     29                         else {
     30                             countSql = _param["countSql"].ToString();
     31                             int cnt = conn.ExecuteScalar<int>(countSql, null, trans);
     32                             sellerModel.CustomerNo = string.Format("PC{0}{1}", DateTime.Now.ToString("yyMMdd"), (cnt + 1).ToString().PadLeft(4, '0'));
     33                             sellerId =conn.ExecuteScalar<int>(sql.ToString(), sellerModel, trans);
     34                         }
     35                         DebugLog("1、客户资料", sql, sellerModel);
     36                         //2、车辆信息,不含车况
     37                         //1),基本信息,手续信息、图片信息、配置信息
     38                         int carId = 0;
     39                         _param = (Dictionary<string, object>)dicParam["carBaseInfo"];
     40                         CarBaseInfoModel carBaseInfoModel = (CarBaseInfoModel)_param["model"];
     41                         sql = _param["sql"].ToString();
     42                         if (carBaseInfoModel.ID > 0)
     43                         {
     44                             conn.Execute(sql.ToString(), carBaseInfoModel, trans);
     45                             carId = carBaseInfoModel.ID;
     46                         }
     47                         else
     48                         {
     49                             carId = conn.ExecuteScalar<int>(sql.ToString(), carBaseInfoModel, trans);
     50                         }
     51                         DebugLog("2、车辆基本信息,手续信息", sql, carBaseInfoModel);
     52                         //2)配置信息
     53                         _param = (Dictionary<string, object>)dicParam["carCi"];
     54                         List<CarCIModel> listCi = (List<CarCIModel>)_param["list"];
     55                         sql = _param["insertSql"].ToString();
     56                         delSql= _param["delSql"].ToString();
     57                         if (listCi.Count > 0) {
     58                             conn.ExecuteScalar(string.Format(delSql, carId),null,trans);
     59                             foreach (var item in listCi)
     60                             {
     61                                 item.CarID = carId;
     62                                 conn.ExecuteScalar(sql, item, trans);
     63                             }
     64                         }
     65                         //3)图片信息
     66                         _param = (Dictionary<string, object>)dicParam["carPic"];
     67                         List<AssessImageModel> listPic = (List<AssessImageModel>)_param["list"];
     68                         sql = _param["insertSql"].ToString();
     69                         delSql = _param["delSql"].ToString();
     70                         if (listPic.Count > 0)
     71                         {
     72                             conn.ExecuteScalar(string.Format(delSql, carId), null, trans);
     73                             foreach (var item in listPic)
     74                             {
     75                                 item.CarInfoID = carId;
     76                                 conn.ExecuteScalar(sql, item, trans);
     77                             }
     78                         }
     79                         //3、 [PingguCarInfo] 车冗余表信息
     80                         int redundanceCarId = 0;
     81                         _param = (Dictionary<string, object>)dicParam["pingguCarInfo"];
     82                         PingguCarInfo pingguCarInfo = (PingguCarInfo)_param["model"];
     83                         sql = _param["sql"].ToString();
     84                         if (pingguCarInfo.Id > 0)
     85                         {
     86                             conn.Execute(sql.ToString(), pingguCarInfo, trans);
     87                             redundanceCarId = pingguCarInfo.Id;
     88                         }
     89                         else
     90                         {
     91                             redundanceCarId = conn.ExecuteScalar<int>(sql.ToString(), pingguCarInfo, trans);
     92                         }
     93                         DebugLog("3、 [PingguCarInfo] 车冗余表信息", sql, pingguCarInfo);
     94                         //4、创建评估单
     95                         int pingguId = 0;
     96                         _param = (Dictionary<string, object>)dicParam["pingguOrder"];
     97                         PingguOrderModel pingguOrder = (PingguOrderModel)_param["model"];
     98                         pingguOrder.CarInfoId = carId;
     99                         pingguOrder.SellerId = sellerId;
    100                         pingguOrder.RedundanceCarId = redundanceCarId;
    101                         sql = _param["sql"].ToString();                  
    102                             countSql = _param["countSql"].ToString();
    103                             int _cnt = conn.ExecuteScalar<int>(countSql, null, trans);
    104                             pingguOrder.PingguNo = string.Format("A{0}{1}", DateTime.Now.ToString("yyyyMMdd"), (_cnt + 1).ToString().PadLeft(4, '0'));
    105                             pingguId =conn.ExecuteScalar<int>(sql.ToString(), pingguOrder, trans);
    106                         DebugLog("4、创建评估单", sql, pingguOrder);
    107                         //5、车况检测信息
    108                         _param = (Dictionary<string, object>)dicParam["carCheck"];
    109                         List<CarCheckItemsModel> listCheck = (List<CarCheckItemsModel>)_param["list"];
    110                         sql = _param["insertSql"].ToString();
    111                         delSql = _param["delSql"].ToString();
    112                         if (listCheck.Count > 0)
    113                         {
    114                             conn.ExecuteScalar(string.Format(delSql, pingguId), null, trans);
    115                             foreach (var item in listCheck)
    116                             {
    117                                 item.CarId = pingguId;
    118                                 conn.ExecuteScalar(sql, item, trans);
    119                             }
    120                         }
    121                     
    122                         //6、保存CarStoreAssociation关系                  
    123                         _param = (Dictionary<string, object>)dicParam["carStoreAss"];
    124                         Model.CarManage.CarStoreAssociation carStore = (Model.CarManage.CarStoreAssociation)_param["model"];
    125                         sql = _param["sql"].ToString();
    126                         carStore.CarID = carId;  
    127                             conn.ExecuteScalar(sql.ToString(), carStore, trans);
    128                         DebugLog("6、保存CarStoreAssociation关系", sql, carStore);
    129                         ret.Status = 1;
    130                         ret.Message = "";
    131                        // throw new Exception();
    132                         trans.Commit();
    133                     }
    134                 }
    135                 catch (Exception ex)
    136                 {
    137                     ret.Status = 500;
    138                     ret.Message = ex.Message;
    139                     Log4NetHelper.Error("APP保存车辆信息时出错:" + ex.Message, ex);
    140                     trans.Rollback();
    141                 }
    142             }
    143             return ret;
    144         }
    View Code

           现在想想,其实就是一个思路的问题,并没有什么难点,项目代码就不贴了,如果真有需要,留下个邮箱好了

  • 相关阅读:
    汽车发动机参数指标含义
    谷歌浏览器Google Chrome和Adobe Flash Plugins插件安装问题
    今天研究成功ASP动态管理数据表及字段
    漂亮的弹出对话框!
    Opera Dragonfly 提供下载了
    javascript客户端验证函数大全
    C# Regex类用法
    只能输入数字的TextBox
    c#,winform,treeview,选中节点,选中相应的全部子节点,取消节点,取消父节点,小技巧
    WinForm中如何判断关闭事件来源于用户点击右上角的“关闭”按钮
  • 原文地址:https://www.cnblogs.com/net515/p/5922608.html
Copyright © 2020-2023  润新知