一个完整的文档服务包含很多对象,以Customer服务为例,它包含以下对象:

  • 查询AxdCustomer:这个query的顶层表为CustTable,其下Datasource包含表DirParty,DirParty下的Datasource则再包含表DirPersonName、表DirOrganizationName、视图DirPartyContactInfoView、视图DirPartyPostalAddressView。这个Query定义了服务所用的所有相关数据的数据模型。
  • 文档服务类CustCustomerService:这是直接提供服务的类,它包含Create、Delete、find、findKeys、getKeys、getChangedKeys等对外服务的方法,这些方法使用特定的特性标注,比如Create方法使用了[AifDocumentCreateAttribute, SysEntryPointAttribute(true)]标注,AifDocumentCreateAttribute指出这个方法是文档服务的创建方法,这个特性不是必须的,主要用途是在使用metadata服务时我们可以根据这个特性列举出所有删除记录的服务操作;SysEntryPointAttribute特性指示是否进行授权检查,所有的服务操作必须指定这个特性,其参数true表示要对调用用户检查是否有权操作该方法涉及到的数据表,false则不执行这个检查。文档服务类服务的具体操作都交由其继承的基类AifDocumentService具体操作,比如read()方法内部调用的是AifDocumentService.readList()方法。
  • 数据对象类CustCustomer、CustCustomer_CustTable、CustCustomer_DirParty、CustCustomer_DirParty_DirPerson等:这些类描述了查询AxdCustomer定义的数据模型,CustCustomer直接对应Query AxdCustomer,它是数据对象类的最顶层,它依靠其他数据类CustCustomer_CustTable、CustCustomer_DirParty等。CustCustomer从AifDocument继承,后者又从AfStronglyTypedDataContainer继承,而AfStronglyTypedDataContainer又从AifXmlSerializable继承,由它描述了XML消息定义的一个文档,所以我们在read()服务操作方法中看到的返回值就是这个类的一个实例。其他的数据对象类都直接从AfStronglyTypedDataContainer继承,所以数据对象类包括CustCustomer都实现一系列的existsXXX()方法,这些方法判断某个字段是否存在,调用基类的exists()方法;一系列parmXXX()方法,获取某个字段的值或者下层的数据对象实例;createXXX()方法,创建并返回其下层的数据对象类实例列表,比如CustCustomer.createCustTable()返回包含CustCustomer_CustTable类实例的列表。
  • 文档类AxdCustomer:文档类的作用是封装涉及到的多个表业务逻辑,这样外部调用应用不需要确切的知道如何操作底层数据库表。Axd类实现AifServiceable接口,这里的AxdCustomer不是直接实现这个接口,而是从AxBase扩展,后者实现AifServiceable接口。总体上来讲Axd类实现到XML的序列化及反序列化,生成XSD数据Schema,控制内部表的生命周期等,由它间接的操作下面要讲到的AxXXX表类。Axd类包含的方法很多,更详细的介绍可以参见http://msdn.microsoft.com/EN-US/library/aa862063.aspx,这里列举几个实现接口AifServiceable比较重要的方法:getName()返回文档的名称,这是XML文档的根标签的名称;getSchema()返回数据Schema XSD;getActionList()返回文档支持的操作列表,比如AxdCustomer支持findList、read、readList等操作。
  • 表类AxCustTable、AxDirPartyTable等:这组类以Ax<Table>方式命名,和文档类协同工作,同样封装数据表业务逻辑,从AxInternalBase继承,代表了AOT中的某个表。Ax<Table>类不是必须的,在使用AIF Document Wizard创建新的文档服务时,勾选了“Generate AxBC Classes”才会创建这些类。如果使用Ax<Table>类,可以在文档级别使用“Value mapping” form来映射数据表字段。Ax<Table>内部使用类AxdBaseRead、AxdBaseCreate读写数据库表,不使用Ax<Table>的情况则可以在Axd文档类中使用AxCommon读写数据库表。需要注意的如果在服务的Query中添加了一个新的表,相应的Ax<Table>类不会自动生成,这时候可以使用Update document service”工具的“Regenerate data object classes”和“Update AxBC classes”选项重新生成或者更新Ax<Table>类。Ax<Table>类和AOT中的表是一一对应的,由它直接操作表数据,具体功能包括生成表字段的默认值、按照正确的顺序设置表字段值、维护验证关联表数据的完整性、字段值映射比如从供应商料名映射到内部料名、错误处理等,需要注意的是Ax<Table>不会验证是谁在操作数据表,用户验证要放到前面提到的服务类。

看完相关的类和对象,在开始后续的问题前,我们先来看看Schema XSD是如何生成的。数据对象类继承自AifDocument(顶级对象),也可能是AfStronglyTypedDataContainer,AfStronglyTypedDataContainer有一个方法叫做getSchema()返回Schema XSD;而AifDocument是继承自AfStronglyTypedDataContainer,它重载了getSchema()方法,它会创建对应Axd类的实例,调用前面提及的Axd类的getSchema()返回Schema XSD。实际上无论是AifDocument.getSchema()还是AfStronglyTypedDataContainer.getSchema(),它们最终都使用AxdBaseGenerateXSD.generate()生成Schema XSD。这里不深入讨论是如何生成XSD的,需要知道的是以上方法会枚举文档定义的Query,从Query中查找Datasource字段生成相应的XML标记,文档Query必须只有一个根Datasource,隐藏或者禁止的字段被排除在外,XML的根元素名称来自于Axd<document>去掉Axd前缀。我们可以用下面的Job从代码生成相应文档服务的XSD:

static void GenerateXSDSchema_Customer(Args _args)
{CustCustomer        customer;XML                 xml;XMLDocument         xmlDocument;FileName            fileName;;// Instantiate the class.customer = new CustCustomer();// Get the document class schema.xml =customer.getSchema();xmlDocument = XMLDocument::newXML(xml);// Save the schema to a file.fileName = "c:\\XSDSchema_Customer.xsd";new FileIoPermission(fileName, 'rw').assert();xmlDocument.save(fileName);CodeAccessPermission::revertAssert();
}

在生成的Schema中我们可以看到AxdCustomer类被映射为complexType类型,其下包含的元素是从AxdCustomer的parmXXX方法去掉parm而来;Query中的表Custtable也映射为complexType类型,名称为AxdEntity_CustTable,包含的元素来自于表字段,只有那些包含在AxCustTable.parmXXX方法的字段才会出现在XSD中。更详尽的字段类型到XSD的单元的映射关系参见http://msdn.microsoft.com/EN-US/library/aa636469.aspx。要说明的是上面得到的文档服务的完整XSD,而我们在端口配置窗口中“View schema”看到的XSD是完整XSD的子集,在“Document data policies”窗口我们可以手工使能或者禁止某个字段,这只是对当期所配置的AIF端口有效。

XSD描述了XML消息的格式,下面是CustCustomerService.read操作得到的XML序列化结果样例(省略部分内容):

  <?xml version="1.0" encoding="UTF-8" ?>
- <Envelope xmlns="http://schemas.microsoft.com/dynamics/2011/01/documents/Message">
- <Header><MessageId>{93FE7B5F-99E6-45D6-BAA5-654699EFF0EA}</MessageId> <Action>http://schemas.microsoft.com/dynamics/2008/01/services/CustomerService/read</Action> <RequestMessageId>{E983D78F-0011-47B7-8716-F8B64D120EF6}</RequestMessageId> </Header>
- <Body>- <MessageParts xmlns="http://schemas.microsoft.com/dynamics/2011/01/documents/Message">- <Customer xmlns="http://schemas.microsoft.com/dynamics/2008/01/documents/Customer"><DocPurpose>Original</DocPurpose> <SenderId>DMO</SenderId> <ValidAsOfDateTime>2012-04-19T19:42:40Z</ValidAsOfDateTime> <ValidTimeStateType>AsOf</ValidTimeStateType> - <CustTable class="entity"><_DocumentHash>261dcc95694f19ee9010b1866237b4a2</_DocumentHash> <AccountNum>4503</AccountNum> <AccountStatement>Always</AccountStatement> <Blocked>No</Blocked> <CashDisc>14D1%</CashDisc> ......<WebSalesOrderDisplay>WebEntered</WebSalesOrderDisplay> - <DirParty xsi:type="AxdEntity_DirParty_DirOrganization" class="entity" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><LanguageId>En-us</LanguageId> <Name>3 Company</Name> <NameAlias>3</NameAlias> <PartyNumber>1310</PartyNumber> <RecId>5637145091</RecId> <RecVersion>1</RecVersion> - <DirPartyPostalAddressView class="entity"><Address>522 West 5th Street New York, NY 10032 US</Address> <City>New York</City> ....<ABC>None</ABC> - <OrganizationName class="entity"><Name>3 Company</Name> <RecId>5637144581</RecId> <RecVersion>1</RecVersion> <ValidFrom>2009-06-13T00:17:00Z</ValidFrom> <ValidTo>2154-12-31T23:59:59Z</ValidTo> </OrganizationName></DirParty></CustTable></Customer></MessageParts></Body></Envelope>

消息包括封皮Envelope和Header段,Header段的Action指定操作的名称。有几点需要说明,注意到Axd类parmXXX被序列化到XML;Query中的表加上了class="entity"属性;如果使用了Ax<Table>,只有Ax<Table>.parmXXX方法指定的内容被序列化,并且由它来读取验证数据,否则数据直接从数据库表读出Query中指定的字段。

我们已经知道文档服务的具体操作是在文档服务类中实现,标准的文档服务操作包括create、delete、find、findKeys、read、update、getKeys、getChangedKeys。在AOT的Services节点下我们可以新建一个Service来引用这些操作,进而在出入站端口中使用。当然不是每一个文档都需要实现上述所有的标准服务,此外我们还可以添加自定义的服务操作,这些自定义服务操作方法必须定义为public,如果参数或者返回值是个对象类,那么这个对象类必须实现AifXmlSerializable接口,如果不是对象类则只有以下几种元类型被支持:str、 date、 utcdatetime、 guid、 int、 int64、 enum、real、void。如何创建一个自定义服务可以参见http://msdn.microsoft.com/EN-US/library/aa607052.aspx。

在findKeys、update、read等方法中用到类AifEntityKeyList,它表示的是一个键值对,比如我们要读取一个Customer的信息,传入的键值对可能是AccountNum=5407。如果我们在自定义的方法中需要返回大量数据,可以考虑只返回记录的键值对,然后再用read方法根据键值对取出实际的记录数据,这有助于提高性能。

后续还有更多关于文档服务的内容......

转载于:https://www.cnblogs.com/duanshuiliu/archive/2013/01/30/2882581.html

[AX]AX2012 AIF(二):文档服务编程模型相关推荐

  1. MFC单文档框架编程(二): SDI框架下的消息处理

    MFC单文档框架编程(一) ...................................................................................... ...

  2. 百度DOC php,PHP对接百度文档服务DOC

    生成认证字符串需要用到的工具类 namespace App\Service; class HttpUtil { // 根据RFC 3986,除了: // 1.大小写英文字符 // 2.阿拉伯数字 // ...

  3. Eolink征文活动---Eolink API文档服务的天才产品

    实际上我并不是因为这次活动才知道Eolink,早在几年前,我就成为了Eolink的使用者,所以,这次征文活动我势在必行!本篇文章将会围绕我如何利用Eolink去解决项目问题进行展开讨论,大致分为以下内 ...

  4. 医疗影像工具LEADTOOLS 入门教程: 在 Windows 服务器上部署 LEADTOOLS 文档服务 - .NET Framework

    LEADTOOLS是一个综合工具包的集合,用于将识别.文档.医疗.成像和多媒体技术整合到桌面.服务器.平板电脑.网络和移动解决方案中,是一项企业级文档自动化解决方案,有捕捉,OCR,OMR,表单识别和 ...

  5. 简单的开源文档服务dokuwiki搭建和配置

    Dokuwiki是一款简单,轻量,支持PHP即可使用,插件丰富,权限控制强大,完全免费,有编辑页面,不懂代码也可以使用.缺点是缺乏对Markdown的原生支持(即使装了插件,也无法完全解析Markdo ...

  6. 关于介绍编程前景的html文档,HTML编程基础稿件(32页)-原创力文档

    * * 第2章 HTML编程基础 优选文档 * 内容提要 本章首先介绍HTML的发展历史,然后介绍HTML的基本框架 详细介绍了HTML的各种常用标记:文字标记.图片标记和超级链接标记,等等. 介绍C ...

  7. android新浪登录接口,新浪游戏AndroidSDK接入文档—服务端.md

    # SNG联运游戏平台接口文档ForCP(服务端) ## 1.用户接口 ### 1.1.用户信息校验接口(服务端) http://m.game.weibo.cn/api/sdk/user/check. ...

  8. OpenCV实践小项目(二) -文档ocr扫描识别

    1. 写在前面 今天整理OpenCV入门的第二个实战小项目, 前一篇文章是信用卡数字识别, 主要运用了OpenCV基础图像处理操作里面的轮廓检测, 边缘检测,形态学操作, 今天的这个项目叫做文档ocr ...

  9. 内网搭建在线文档服务

    步骤 安装 Node 和 NPM: 安装 git, gitbook,gitbook-cli: 配置 Gitlab Webhook: 创建 Webhook 监听服务: 编辑文档检查实时更新: 安装 No ...

最新文章

  1. python基础学习笔记(十三)
  2. 记得5年前左右的时候,IT这块刚好处于最火专业之一!至今为止,依旧很多人选择计算机!由于女生也很多选择这块,所以给很多公司带来了福利啊!以前一个互联网公司女生少的可怜啊!可随着IT这块人员的进入,竞争
  3. oracle10g 开机自启动
  4. 电脑微信扫一扫在哪_13个微信隐藏技巧,至少有10个你不知道
  5. Rich feature hierarchies for accurate object detection and semantic segmentation(理解)
  6. python绘制多条不同x轴曲线_python matlibplot绘制多条曲线图
  7. HTML知识积累及实践(六) - pre,混合框架
  8. Windows 7 一年试用批处理
  9. 【OpenCV 例程200篇】201. 图像的颜色空间转换
  10. 前端开发必备基础英文单词整理汇总
  11. Kubernetes 深入理解 Pod
  12. 利用Meshlab旋转三维点云模型
  13. puppet的使用:ERB模板介绍
  14. FPGA学习:Verilog基本语法
  15. win10 win11关睿频(打开隐藏的“处理器性能提升模式”)
  16. 在拍拍二手爱回收出过一次手机后,我才体验到回收二手的快乐
  17. 安装从GitHub下载的包
  18. 搭建PXE自动安装centos
  19. xmind可以画流程图吗_xmind8可以画流程图吗
  20. ecs服务器网站目录,ecs云服务器的根目录

热门文章

  1. C++(STL):21---deque之源码剖析
  2. 怎么关闭或者卸载ivanti_电脑软件卸载不了怎么办,教您解决电脑软件无法卸载方法技巧...
  3. std::reserves使用
  4. 线程安全和对应的核心概念
  5. 专访阿里云总裁王文彬:做出“用得爽”的工程产品
  6. 45度做人 90度做事 180度为人 360度处事
  7. VC画图用到的主要方法
  8. 解决:ClassNotFoundException: com.netflix.hystrix.contrib.javanica.aop.aspectj.HystrixCommandAspect
  9. 《 追风筝的人 》:“ 为你,千千万万遍 ” ...
  10. lambda表达式与委托与线程初步谈论-基于刘铁锰视频观后操作