利用IExtendProvider简化Entity和UI数据交换
创始人
2024-04-05 04:51:06
0

大家知道UpdateData就是将从UI的各个控件的属性中读取数据,在赋值到实体的属性中;UpdateUI就是反过来,从实体的属性中读取数据,再赋值给UI的各个控件的属性。

先举个例子:

  1. public void UpdateUI(TTicketSaleBill ticketSaleBill)  
  2. {  
  3.     ....  
  4. edit_CreatorId.StringValue  = ticketSaleBill.CreatorId;   
  5.     edit_CreateDateTime .DateTime  = ticketSaleBill.CreateDateTime ;   
  6.     edit_ModifierId.StringValue = ticketSaleBill.ModifierId ;   
  7.     edit_ModifyDateTime .DateTime  = ticketSaleBill.ModifyDateTime ;   
  8. }  
  9. public void UpdateData(TTicketSaleBill ticketSaleBill)  
  10. {  
  11. ....      
  12.     if(ticketSaleBill.PersistState == Fx.Common.Data.TPersistState.Added)  
  13.     {  
  14.  ticketSaleBill.CreatorId = this.Context.SecurityCtx.LoginUser.Id ;   
  15.  ticketSaleBill.CreateDateTime = DateTime.Now;   
  16.     }  
  17.     ticketSaleBill.ModifierId = this.Context.SecurityCtx.LoginUser.Id;  
  18.     ticketSaleBill.ModifyDateTime = DateTime.Now;     

如果实体的属性数据比较少,这么写没什么问题。但是复杂的实体动则10几个属性,写起来看了都怕。因此,有了一个叫做代码生成器的东西,可以自动生成UI的代码,省掉了一些体力劳动。但是,我们不是仅仅写了一次就ok,有时还要修改。不小心改了一个名字忘了点重构就直接吐血而亡。况且,那么一大堆的代码在那里也不是一成不变,有时候改了类型还得加上强制转换。有时为了方便,我们还会建立一个字典,将UI控件和实体的属性对应起来。

本人也属于懒人,之前也搞过用字典映射,但始终觉得不够人性化,就总琢磨着怎么给这个方法来个升华。毕竟UI都是这个东西再怎么生成,多少还是要用到IDE的可视化功能吧,如果能向设置属性那样,设置哪个属性对应哪个控件是否会好些?

不要太复杂,直接输入实体属性的名称、控件属性的名称、是否允许空值、是否只读对于数据交换来说就够了吧。要实现这个必然要扩展原来那些标准控件,向devExpress那样的第三方控件学习,似乎没那么干劲自己写。于是就以ToolTip为榜样,用IExtenderProvider来实现所需的功能。

首先定义一个MappingInfo来存储上面说到的信息。再来就是定义一个对象(我的叫UIMapper),实现IExtenderProvider(这一步没什么好说的了,关键是ProvidePropertyAttribute别设置错误,否则啥都扩展不出来)。提供2个方法,UpdateData和UpdateUI并针对DataRow和object的重载。然后就大功告成。在需要数据交换的地方之需要简单调用UpdateData和UpdateUI即可。比如上面的那小段代码就可以改为UIMapper1.UpdateData(ticketSaleBill)或这UIMapper1.UpdateUI(ticketSaleBill)。

IExtendProvider使用总结:

1、对于属性的赋值。有时候我们可能需要要对UI控件更深一个层次的属性赋值或取值,比如devExpress那些Edit常用的XXEdit1.Propertys.XXValue为了实现这个功能只好首先自己动手,按“.”分割字符串,然后利用反射逐级获取对象的实例。而且在嵌套发生时,并不能确定是Property还是Field,为了应对不同的情况BindingFlag最好设为BindingFlags.Static | BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.NonPublic | BindingFlags.GetProperty | BindingFlags.GetField,然后利用InvokeMember来执行操作。

2、利用反射+Converter能实现大部分类型的转换,但不能针对所有的类型。目前的做法是增加QueryObjectValue的事件,用于在赋值时由用户处理特殊的类型转换。

3、在赋值发生异常时同样通过事件通知用户,由用户决定处理的方式。在UpdateUI或UpdateData调用结束之后,返回Dictionary即控件和异常的字典。

4、用IExtenderProvider实质上也是用Dictionary来实现扩展,但其在设计时可以直观进行编辑,在运行时也可以简单方便地进行扩展。

5、 虽然反射的速度要比直接赋值慢,但是在这种情况下还是可取的。特别是当实体的属性较多或者数据库表字段较多的情况下,可以在设计时直接设置,减少了代码量。

【编辑推荐】

  1. Java连接MySQL中文乱码处理
  2. 在Java应用程序中使用Jfreechart配置
  3. Java虚拟机内部构成浅析
  4. 浅谈Java线程的生命周期
  5. 关于Java继承的一些复习

相关内容

热门资讯

如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
施耐德电气数据中心整体解决方案... 近日,全球能效管理专家施耐德电气正式启动大型体验活动“能效中国行——2012卡车巡展”,作为该活动的...
20个非常棒的扁平设计免费资源 Apple设备的平面图标PSD免费平板UI 平板UI套件24平图标Freen平板UI套件PSD径向平...
德国电信门户网站可实时显示全球... 德国电信周三推出一个门户网站,直观地实时提供其安装在全球各地的传感器网络检测到的网络攻击状况。该网站...
为啥国人偏爱 Mybatis,... 关于 SQL 和 ORM 的争论,永远都不会终止,我也一直在思考这个问题。昨天又跟群里的小伙伴进行...
《非诚勿扰》红人闫凤娇被曝厕所... 【51CTO.com 综合消息360安全专家提醒说,“闫凤娇”、“非诚勿扰”已经被黑客盯上成为了“木...
2012年第四季度互联网状况报... [[71653]]  北京时间4月25日消息,据国外媒体报道,全球知名的云平台公司Akamai Te...