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

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

如题,项目的持久层用的是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(),
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)》里有一些唠叨。

懒汉处理dapper字段名与属性名的映射方式的更多相关文章

  1. mybatis03--字段名和属性名不一致

    1.修改数据库中的字段 2.运行根据id查询所有的学生信息的测试方法会出现下面的异常 也就是说明 数据库中的字段没有个实体类中的属性名一致 3.修改StudentMapper.xml文件中的列名 4. ...

  2. js获取对象属性的两种方法,object.属性名,[‘属性名’ ]

    1.通过点的方式 2.通过括号的方式 例: <input type="text" value="hello" id="text"/&g ...

  3. java jackson 忽略不存在的属性字段 和 按照属性名转json

    @JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, isGetterVisibi ...

  4. 字段名与属性名不一致问题 通过resultMap解决

  5. MyBatis学习总结(四)——解决字段名与实体类属性名不相同的冲突(转载)

    本文转载自:http://www.cnblogs.com/jpf-java/p/6013307.html 在平时的开发中,我们表中的字段名和表对应实体类的属性名称不一定都是完全相同的,下面来演示一下这 ...

  6. MyBatis入门学习教程-解决字段名与实体类属性名不相同的冲突

    在平时的开发中,我们表中的字段名和表对应实体类的属性名称不一定都是完全相同的,下面来演示一下这种情况下的如何解决字段名与实体类属性名不相同的冲突. 一.准备演示需要使用的表和数据 CREATE TAB ...

  7. MyBatis学习总结(四)——解决字段名与实体类属性名不相同的冲突

    在平时的开发中,我们表中的字段名和表对应实体类的属性名称不一定都是完全相同的,下面来演示一下这种情况下的如何解决字段名与实体类属性名不相同的冲突. 一.准备演示需要使用的表和数据 CREATE TAB ...

  8. MyBatis——解决字段名与实体类属性名不相同的冲突

    原文:http://www.cnblogs.com/xdp-gacl/p/4264425.html 在平时的开发中,我们表中的字段名和表对应实体类的属性名称不一定都是完全相同的,下面来演示一下这种情况 ...

  9. MyBatis学习总结_04_解决字段名与实体类属性名不相同的冲突

    一.准备演示需要使用的表和数据 CREATE TABLE orders( order_id INT PRIMARY KEY AUTO_INCREMENT, order_no VARCHAR(20), ...

随机推荐

  1. 对于adc dac使用细节

    1. 要更具内部线路图决定引脚分配,adc和dac绑定在一个线路上,所以设计的时候最好尽量间隔三个引脚以上,如果adc必须放到一起,请使用开关控制,但是dma等可能不能正常工作. 2.dac输出内部缓 ...

  2. 简单示例用例(Simple Example Use Cases)--hive GettingStarted用例翻译

    1.MovieLens User Ratings First, create a table with tab-delimited text file format: 首先,创建一个通过tab分隔的表 ...

  3. 开启spark日志聚集功能

    spark监控应用方式: 1)在运行过程中可以通过web Ui:4040端口进行监控 2)任务运行完成想要监控spark,需要启动日志聚集功能 开启日志聚集功能方法: 编辑conf/spark-env ...

  4. MySQL命令:select查询语句

    SQL 中最常用的 SELECT 语句,用来在表中选取数据. 要记得的知识点如下: SELECT 语句格式: SELECT 要查询的列名 FROM 表名字 WHERE 限制条件: WHERE语句后: ...

  5. flannel

    Docker跨主机容器间网络通信实现的工具有Pipework.Flannel.Weave.Open vSwitch(虚拟交换机).Calico实现跨主机容器间的通信.其中Pipework.Weave. ...

  6. 优化网站设计(七):避免在CSS中使用表达式

    前言 网站设计的优化是一个很大的话题,有一些通用的原则,也有针对不同开发平台的一些建议.这方面的研究一直没有停止过,我在不同的场合也分享过这样的话题. 作为通用的原则,雅虎的工程师团队曾经给出过35个 ...

  7. readonly enable

    <input type="text" id="UserName" style="width:20%;" disabled=" ...

  8. Sleep 等待连接攻击

    Sleep The thread is waiting for the client to send a new statement to it. https://dev.mysql.com/doc/ ...

  9. ios 数组打乱顺序

    -(NSMutableArray*)getRandomArrFrome:(NSArray*)arr { NSMutableArray *newArr = [NSMutableArray new]; w ...

  10. Linux下MySql的配置文件my.cnf详细 讲解

    经常在使用MySql,但是对于MySql下面的各种参数的配置并不是很熟悉,经常在需要改变某项参数的时候,还要到处在网上查找,有点不方便.今天想把MySql下面的配置文件my.cnf详细的做一个说明(L ...