Dynamics AX中Table Map的点点滴滴
在Microsoft Dynamics AX的MorphX中,AOT下有个Maps节点(注意,不是Map Class),这个节点下罗列了所有的Table Mapping。很多开发人员对于Table Mapping的概念不是很清楚,在使用过程中也会遇到一些问题。本文简单地收集并罗列一下。
一、Table Mapping也是Table
在AOT上,任意选择一个Table Map,单击鼠标右键选择Open,即可打开Table Browser。当然,如临时表一样,里面什么东西都没有,但我们可以看到,MorphX将Table Mapping当做Table处理了。
不仅如此,我们还可以直接使用SysDictTable类来获得Table Mapping的一些反射属性。比如:
static void Job28(Args _args)
{
SysDictTable sysDictTable = new SysDictTable(tableNum(AddressMap));
;
print sysDictTable.isMap();
pause;
}
二、Map是Table的抽象
在谈Map与抽象之间的关系之前,先看看应该如何理解Dynamics AX中Table的概念。其实Table可以理解为业务实体类,它里面同样包含属性(Fields)和方法(Table Methods)。既然可以当成是实体类,那么就可以对其进行抽象。事实上,Dynamics AX中的Common表,就是所有数据表(或者说所有实体类)的基类,因此,在不确定传入的具体是那张表的情况下,我们往往会使用Common来定义函数的参数或者返回值。比如:
public final void writeLog(WebRecordName _recordName,
Common _orig,
Common _now,
WebExportLogType _exportLogType = WebExportLogType::AddOrModify,
DivisionId _divisionId = SysUserInfo::find(curUserId()).DivisionId,
boolean _force = false,
WebExportRemark _remarks = '')
{
// ...
}
现在随便想一个应用场景:系统中有两种用户类型:Individual Person和Organization。这两种用户类型都需要向系统提供用户名和密码,以便确认身份,进而获得更多其他的服务。那么这个校验身份的函数,就需要获得请求者的用户名和密码。我们定义两个Table:Person和Organization;以及一个Map:AuthenticationMap,如下:
于是,我们的校验方法就可以写成这个样子:
boolean authenticate(AuthenticationMap _authMap)
{
return this.checkAuthentication(_authMap.UserName, _authMap.Password);
}
从上面的代码还可以看到,Table Map“解耦”了Table的设计,在“用户名”和“密码”两个属性上,Person和Organization甚至可以使用不同的名字,最后只要用Map链接一下就可以了。
三、在Table上调用Map中的方法
其实方法很简单,只需要在Table的实例上,用“.”运算符调出Map,进而使用“::”运算符调用Map中的方法即可。注意:X++ Editor的智能感知功能是无法在您输入“.”以后,将Map列出的。此时关闭智能感知,直接用键盘敲入。
例如:我们在上面的AuthenticationMap上定义了一个isStrongPassword的instance方法:
boolean isStrongPassword()
{
return strlen(this.Password) >= 8;
}
那么在插入Person表记录的时候,我们需要首先判断输入的密码是否为强密码,否则禁止新建记录。在Person这个Table上,重载insert方法,并在方法中调用AuthenticationMap的isStrongPassword方法即可:
public void insert()
{
if (this.AuthenticationMap::isStrongPassword())
super();
else
checkFailed('The password is not strong enough!');
}