buguge - Keep it simple,stupid

知识就是力量,但更重要的,是运用知识的能力why buguge?

导航

懒汉思维处理dapper字段名与属性名的映射方式

你还以为走路是世上最简单的事情呢?只不过是把一只脚放到另一只脚前面。但我一直很惊讶这些原本是本能的事情实际上做起来有多困难。而吃,吃也是一样的,有些人吃起东西来可困难了。说话也是,还有爱。这些东西都可以很难。

--摘自蕾秋·乔伊斯《一个人的朝圣》

 

如题,项目的持久层用的是dapper,有一些复杂的报表需要自己编写sql。 通过dapper返回一个泛型数据集合。这个泛型类T通常就是我们所定义的一个DTO,如下代码中的ZhifuDuizhangBaobiaoDTO。

开发过程中,数据表字段的命名并不规范,我在开发这个报表时重新定义了一下DTO的属性名。这时,sql里就要用到as了。

public static List<ZhifuDuizhangBaobiaoDTO> GetDuizhangBaobiao(ZhifuDuizhangBaobiaoQueryModel query, PageModel pageModel)
{
    string sql = @"SELECT ZFDate as 'OrderPayDate', OrderNo, orderId, ChannelNo, OrderAmount as 'Amount', orderst as 'OrderStatus', mercode
FROM t_business_airorders a
WHERE ZFDate>=@dateFr AND ZFDate<@dateTo
AND payType>1 ";

    // 参数值判断
    if (null != query.OrderNo && query.OrderNo.Trim() != "")
    {
        sql += " AND a.OrderNo=@OrderNo";
        query.OrderNo = query.OrderNo.Trim();
    }
    if (null != query.ChannelNo && query.ChannelNo.Trim() != "")
    {
        ......
    }

    var dp = new Object();
    dp = new
      {
          dateFr = query.OrderPayDateFr.Date,
          dateTo = query.OrderPayDateTo.Date.AddDays(1),
          OrderNo = query.OrderNo,
          ChannelNo = query.ChannelNo,
      };

    sql += " order by a.ZFDate desc";
    using (var conn = ConnUtility.GateWayConntion)
    { 
        var pagedList = conn.MySqlPageList<ZhifuDuizhangBaobiaoDTO>(sql, pageIndex: pageModel.PageNo, pageSize: pageModel.PageSize, param: dp);
        pageModel.RecordCount = pagedList.recordCount;
        var lst = pagedList.listT;
        return lst.ToList(); 
    }
}

与前端的视图页联调通过后,这样的代码可以fix了。

 

不过,上面的代码其实是有隐形错误的——当日后重命名ZhifuDuizhangBaobiaoDTO的OrderPayDate、Amount属性时,很容易忽略这段sql文本里的as。

那么,为了能应对日后的扩展和重构,我采用了另一种方式,利用linq的Expression表达式来读取属性名。 

public static List<ZhifuDuizhangBaobiaoDTO> GetDuizhangBaobiao(ZhifuDuizhangBaobiaoQueryModel query, PageModel pageModel)
{
    string sql = @"SELECT ZFDate as '{0}', OrderNo, orderId, ChannelNo, OrderAmount as '{1}', orderst as '{2}', mercode
FROM t_business_airorders a
WHERE ZFDate>=@dateFr AND ZFDate<@dateTo
AND payType>1 ";

    sql = string.Format(sql, GetPropertyName<ZhifuDuizhangBaobiaoDTO>(c => c.OrderPayDate),
        GetPropertyName<ZhifuDuizhangBaobiaoDTO>(c => c.Amount),
        GetPropertyName<ZhifuDuizhangBaobiaoDTO>(c => c.OrderStatus));

    ......
}

 这里借助了一个GetPropertyName<T>方法。

using System.Linq.Expressions;

public
static string GetPropertyName<T>(Expression<Func<T, object>> expr) { var rtn = ""; if (expr.Body is UnaryExpression) { rtn = ((MemberExpression)((UnaryExpression)expr.Body).Operand).Member.Name; } else if (expr.Body is MemberExpression) { rtn = ((MemberExpression)expr.Body).Member.Name; } else if (expr.Body is ParameterExpression) { rtn = ((ParameterExpression)expr.Body).Type.Name; } return rtn; }

 墨菲定律里有说“会出错的事总会出错”。一个在开发中的项目,经常因review或代码分析而改一些代码的。这样就一劳永逸了。日后重构属性名,我们就不用担心这块了。

BTW,在MVC视图页里,我们要显示模型的显示名称,经常这样写@Html.DisplayNameFor(model => model.OrderPayDate),当属性没有DisplayNameAttribute时,就会返回属性名。

 

今天突然想到了“懒汉思维”这个词,是为了记念公司里之前的一位产品经理大神,周缘昕。我们公司的企业用车产品能够在企业出行市场占据一席之地,少不了他的倾心贡献。NB之大,百度一下,你就知道。那时有幸参加他为产研同事做的一个培训,其中谈到了产品设计的“懒汉思维”。一个产品经理把一个需求设计合理并讲清楚,并不是一件容易的事情。同样,后期的运营跟进同样不是易事。  之于系统开发方面,又何尝不是呢。在我去年的文章《运维一个应用系统不容易(2016-07-29 18:43)》里有一些唠叨。

 

懒汉思维也是一种成功的智慧。也许,在正常人的思维词典里,懒汉就是不思进取、不求上进,就是偷懒,就是恶习。其实,这样理解是片面的。那些成功的人士,那些牛X的人士,往往具备懒汉思维。他们非常善于做自己喜欢的和自己认为重要的事,而其他不重要的事情,能不做就不做,能推迟就推迟,能让他人支持的就让他人做,实在非自己做不可的,也会想个一劳永逸的方式。假如你把大量的精力和时间耗费在日复一日的重复的事情上,你就没有时间get更多的技能知识或其他领域。也许对你目前从事工作相关的信息和思想,你会错过,这样,你的成长就比较有限,也就会离成功或牛X越来越远了。

 

posted on 2017-02-28 20:03  buguge  阅读(749)  评论(0编辑  收藏  举报