一,前言
现实业务当中,有一个很常见的流程:从数据库获取数据到DataTable,然后将DataTable绑定到实体类集合上,一般是List<Class>,代码写起来也简单:遍历+赋值就可以了。
但是,代码逻辑虽然简单,代码量不小,而且代码往往很臃肿。本篇文章就来一步步对这种业务代码进行优化。
本文使用C#进行实现及演示。
相信看完的你,一定会有所收获!
本文地址:https://www.cnblogs.com/lesliexin/p/15307862.html
二,基础写法
就像前言所说,代码逻辑很简单——遍历+赋值,我们来看一下最基础的写法。
看起来还好,但是,DataTable是存在空值情况的,而空值在实际业务中是个很严重的存在,所以我们需要对DataTable中的空值进行判断。改造后的代码如下:
如果没经历过太多业务代码的读者可能觉得这样看起来也还好,这是因为我为了演示,只设计了几个字段,但在实际业务中,往往都是几十个字段,甚至上百个字段,而且字段名也不是就“AAA”这样三个字母,而是十几、二十几个字母;当写出来时,好几页屏幕都是这种代码,别提有多刺激了。
而且,这里演示时所有属性字段都是string类型的,现实中肯定不是这样,会有int,double,Datetime,bool等等类型,那样代码量会“更胜一筹”,这点在下文会讲。
三,第一步优化
看了上面的代码,可以发现,绝大部分代码都是重复的三元判断,所以在实际写代码时,我都是用Excel的下拉复制功能去写的^_^
我们第一步的优化,就是将这个三元判断优化掉,方法是使用扩展方法,在扩展方法里实现三元判断,并返回我们需要的值。
我们新建一静态类,并新建一扩展方法如下:
有了扩展方法后,我们的代码就可以改成下面这样:
立马简洁了好多有不有!
四,第二步优化
就像上面所说的,不可能所有的属性字段都是string类型的,会有int,double,Datetime,bool等等类型,这就涉及到类型转换的问题。加上类型转换后,不管是使用Convert还是TryParse,代码就又会臃肿了起来。
所以,我们要将这些类型转换给优化掉,优化的方式同样是采用扩展方法,将类型转换包含在扩展方法中。
使用了扩展方法后,代码相较之前前简洁了不少。
五,第三步优化
这时候,我们发现了另一个问题,就是扩展方法太多了。
而且,可以预见的是,随着属性类型的增多,肯定要编写对应的扩展方法,比如:StrToInt(),StrToLong()等等。
同时可发现这些类型转换的扩展方法都是一样的逻辑,所以我们这一次就优化类型转换的扩展方法。
我们新建一个泛型扩展方法,以支持将string转换成指定类型。
这样下来,所有类型转换的扩展方法就变成这一个扩展方法,在使用时只需要写上对应的类型即可。
六,第四步优化
这种时候,有小伙伴就要问了,既然都是依次调用这两个扩展方法,那能不是将这两个再合并一下?当然可以!
我们再改造一下扩展方法,将这两步合而为一。
这种时候,赋值的代码就变成成了这样。
一切仿佛发生了改变,一切又仿佛从未改变。
七,第五步优化
一般而言,到第四步时,已经足够优化了,使用起来也足够简单,代码逻辑也清晰,但是,这还不够,因为还要重复的去一行一行的赋值,都是一样写法,就不能优化掉吗?!
所以这一步我们就将这些给优化掉。
这里面涉及到两个重点,一个是获取类里的属性信息,包含属性名和属性类型;一个是获取DataTable中相应的值并转换为相应的类型。
同时,因为存在属性名与列名一样但大小写不同的情况,也需要进行判断。
实现了这个扩展方法,赋值部分的代码就可以简化成一行代码。
很惊艳是不是?原来要写很多行的代码,现在一行就搞定了,很舒服有不有!
八,第六步优化
什么?还要优化?还能优化?当然可以!
上面的优化只能针对属性名与列名一致的情况,当属性名与列名不一致时,怎么办?
而这,就是我们这一步优化的目标。
为了解决属性名与列名不一致的问题,我们需要用到特性标签,我们新建一个特性类,里面包含一个属性,用来指定属性名所对应的列名。
同时,我们改造下上一步的扩展方法ToList<T>,增加对特性标签的获取与判断。
使用时,在实体类上添加上特性标签即可,比如类的属性“AAA”要取DataTable中列“FFF”对应的值,则在属性“AAA”上加上特性标签“[DT("FFF")]”,其它不需要作任何改变。
九,结束语
至此,经过六步的优化,“从数据库获取数据到DataTable,然后绑定到List<Class>”这一流程的业务代码已经优化完毕,使用时只需要一行代码即可达到目标。
当然,现实中的业务流程肯定千奇百怪,复杂性也不尽相同。本篇文章只是提供一个优化业务代码的思路,以及在特定情况下,可以直接套用本文代码,以节省开发时间,提高开发效率。
感谢阅读,欢迎大家评论指正!