利用IExtendProvider简化Entity和UI数据交换

开发 开发工具
不管是用DataRow用字典还是用Entity都免不了和UI的数据交换,比较传统且经典的做法是在UI上添加2个方法:UpdateData和UpdateUI。本文将谈谈利用IExtendProvider简化Entity和UI数据交换

大家知道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使用总结:

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

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

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

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

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

【编辑推荐】

  1. Java连接MySQL中文乱码处理
  2. 在Java应用程序中使用Jfreechart配置
  3. Java虚拟机内部构成浅析
  4. 浅谈Java线程的生命周期
  5. 关于Java继承的一些复习
责任编辑:彭凡 来源: cnblogs
相关推荐

2010-01-06 14:36:04

JSON插件

2009-11-09 17:17:31

WCF元数据交换

2023-07-19 19:45:12

EDI人工智能

2010-01-15 10:19:42

数据交换技术

2018-08-31 21:00:39

数据交换模型数据模型应用程序

2019-11-22 08:40:19

ProtobufGo编程语言

2009-01-03 14:54:40

ibmdwXML

2010-03-02 10:50:57

WCF元数据交换

2011-08-19 13:45:14

iPhone应用iPhone OS数据

2012-09-26 09:51:11

电子政务数据交换

2010-02-04 11:15:12

数据交换技术

2012-01-04 00:10:52

ibmdw

2009-01-19 09:28:42

JSONJavaScriptJSON结构

2011-08-25 16:53:42

Lua数据 交换

2009-11-06 10:45:47

WCF服务元数据交换

2009-11-06 10:25:34

WCF元数据交换

2010-02-04 11:32:01

数据交换技术

2010-02-04 11:20:29

网络数据交换技术

2022-02-21 10:29:26

物联网招聘IOT

2010-01-08 13:40:26

点赞
收藏

51CTO技术栈公众号