关于关系
关系是建立对象类之间的数据关联。它们定义了一个源对象类和关联对象类。它可以这样描述:
这里Relationship1把ItemType1和ItemType2联系在一起。每个关系都可以由两个独立的对象组成,关系类型(Relationship Type)和关系对象类(Relationship ItemType)。关系对象类可能和其他对象或是其他关系有关联。这种表现形式允许复杂数据模型的最大程度的灵活性要求。如果你的业务流程要求复杂的数据模型,你想要使用嵌套关系。请联系Aras解决方案的顾问寻求帮助。在本手册里面,我们将会实现一般的源对象绑定关联对象的简单的关系结构。
源对象类可以使用关联对象类的所有属性。例如:如果我们定义一个关系类型叫做文档(Documents),源对象是零部件(Part),关联对象是文档(Document),对于一个特有的零部件实例,它可以访问关联的文档实例的所有属性值。
源对象类可以有多个关系,在对象实例中,每个定义好的关系对应一个页签。例如:零部件定义了9个关系类型。如下图,它们显示在对象类定义界面的“关系类” 页签下。
所以这个对象类定义完后,零部件的实例就有九个页签-每一个对应一个关系
打开源对象实例的一个关系页签,可以通过选择或是创建(采用哪种方式依赖于关系的定义)方式添加关联对象。所有关联对象将会列在对应关系页签下的关系网格内。下图为关系网格样例:
在后续部分我们将学习怎么创建一个关系,怎么设置它的属性和定义它的操作,步骤如下:
1. 创建源对象类和关联对象类;
2. 从源对象类创建和命名关系;
3. 修改关系类型对象---修改关系自身行为;
4. 修改关系对象类----添加或编辑关系自身属性(例如:数量属性)。
创建相关对象类
在创建关系之前,你需要预先定义希望关联的对象类。下例中我们将会定义两个对象类:Housekeeping Planner和Contractor。下图为HousePlanner的定义界面,它基本定义了名称,需要服务的房屋地址和需要的服务类型等基本属性。
注意这 五个属性是最基本的定义。将要关联到HousePlanner对象类是Contractor。下图是它的定义界面:
注意Contractor同样只有五个属性,像类型,由可选列表控制,地址,名称,电话号码和可靠性评估。现在我们定义两个对象类之间的关联,请看下节“定义关系”。
定义关系
一个关系绑定两个对象-源对象和关联对象,它实现了通过源对象直接获取关联对象信息。关系从源对象上开始,创建一个链接到关联对象。另一种方法为直接创建一个关系类型对象。第二种方式在某些特殊情况下是非常必需的,比如为所有的对象创建一个关系而不是一个特定的源对象。更多相关信息请参考“关系类型”。
创建一个关系
1. 打开并编辑源对象类定义界面,此例中,源对象为HousePlanner;
2. 点击源对象的“关系类”页签,界面如下:
3. 在执行旁边的下拉框中,有两个选项:选择对象和无对象。这些选项与关联对象有关。如果关联对象已存在,可以选择“选择对象”。如果关联对象不存在,同样可以创建关系,但是这个时候要选择“无对象” 选项。本章稍后将详细介绍“无对象”。现在,确认下拉框中 “选择对象”已选定,然后点击新建图标 ,一个关联对象的查询对话框将显示。
在我们的例子中,选择“Contractor”对象然后点击绿色的选择标记按钮 。
4. 一个新的关系行将自动创建,关联Item也已经填写。下一个步骤是填写余下的必需属性。下图为新关系:
填写下列属性的值
a. 页签序号
b. 关系名称—填写关系名称。一个关系类型和一个关系对象类将会根据名称自动创建。我们将会在下面继续讨论这两个对象。
c. 页签标题—源对象实例的页签标题用来标识关系并包含到关联对象的引用。参考“页签示例”。
d. 名称—关联对象类的名称。
e. 描述—关联对象的描述,如果关联对象有描述属性字段并且已经填写,那么系统将自动填写。下图为填写了属性值的关系页签。
6. 保存,解锁并关闭或者保存HousePlanner对象。
源对象一保存,另外两个对象马上自动创建-关系类型和关系对象类。它们的名称都与上面关系类名称列显示的名称一样,在本例中为“Contractor Rel”。
关系类型对象控制关系本身的行为,关系对象类是控制关系本身的属性。我们将在以下章节详细讨论这两个对象。
1. 关系类型对象
2. 关系对象类
创建一个没有关联的关系
现在我们来实验一下从源对象创建没有关联的关系的时候将会发生什么。因为将创建一个关系,仍然需要打开源对象类的关系页签,但是将会没有关联对象链接到它,如下例。
1. 打开HousePlanner ItemType ,再添加一个关系,如下图:
注意:没有关联的关系会被标注上 图标。
2. “保存 解锁并关闭”HousePlanner 对象类。关系类型CommentRel和CommentRel 对象类立即在系统中自动创建。我们编辑CommentRel对象类,为它添加一些属性。
3. 点击TOC中的系统管理->对象类 ,找到CommentRel 对象类并打开编辑
4. 添加一个属性叫做Comments ,取消Created_by_id和created_on的“在关系中隐藏”;
1. 保存,解锁并关闭CommentRel 对象类。
2. 现在我们创建一个HousePlanner实例。点击Comments标签页,填写comment然后保存Item。这就像这样(created_on和created_by_id被系统自动填写和保存)
以上部分中我们探索了当一个源对象的关系被创建时,没有关联对象会发生什么。
根据你的数据建模需要这可以成为一种有效的方法。
修改关系类型对象
当源对象的关系被创建之后,关系类对象立即自动创建。关系类位于TOC的系统管理文件夹下。但是,我们不能创建关系类本身(一个例外情况,参考创建一个独立的关系类型)只能通过源对象类来创建。
在本例中,我们创建了一个从源对象类HousePlanner到相关对象类Contractor的关系,它叫做ContractorRel。现在,我们测试一下ContractorRel。
编辑关系类型的属性
1. 点击TOC 的“系统管理”文件夹, 选择关系类,搜索ContractorRel对象,然后打开并编辑。
2. 让我们先看上面的属性,它们控制关系本身的行为。
属性名 | 描述 |
名称 | 关系名称,在源对象类的关系类中给定。 |
标签 |
源对象对象实例的页签标签显示.
在该页签下,所有的相关对象实例(此例中为Contractors)将显示在关系网格中。 |
描述 | 关系的描述 |
自动搜索 | 当选中时,自动以关系对象实例填充关系网格(即自动查找关系页签下的实例对象). 注意:关系网格位于源对象类实例的关系页签下。 |
序号 | 决定源对象类中,页签的显示位置。 |
默认页面大小 | 设置源对象的关系页签中关系网格显示的页面数据条数。 |
源对象类 | 关系的"父对象"对象类的唯一标识名称。每个关系类只能定义一个源对象类, 它在关系创建时自动设定。 |
在所有页面隐藏 | 该选项只有当源对象未指定时适用。因此,关系把所有的对象类做为源对象,并创建一个所有对象类和相关对象类之间的关系.用户可以选中此选项,隐藏所有对象下的该关系页签。 |
相关对象类 | 相关对象.根据源对象类的关系定义自动填充。 |
最小出现 |
设置关系网格包含的最小对象数。
以上网格有4行记录. 如果最小出现设置为5,保存时将提示错误信息. |
最大出现 | 设置关系网格所包含的最大对象数. 参考最小出现. 它有4行. 如果此处设置为 3,保存时也将提示错误信息。 |
行为 |
只有当相关对象可换版时适用, 参考如下规则,决定哪个版本的相关对象绑定至源对象: |
网格显示 |
关系网格显示两类属性- 相关对象的属性,和关系自身的属性. 网格显示的可选值如下: 网格显示一般与对象类中属性的序号共同决定属性在行中的显示次序. 在关系中, 相关对象的属性可以设置序号,关系对象类自身的属性也可以设置序号。 考虑下面的示例. 零部件对象通过BOM关系与其他零部件关联. 零部件对象类的名称属性的序号为10,零部件编号的序号为20。 BOM关系也有一些属性,其中一个叫做数量,序号为15。 下面为网格显示设置为Left时的BOM页签视图。 注意:关联对象的属性列出现在左边。 并且,相关零部件先按照Name排序,其次根据Part Number。
下面为网格显示设置为Right时的BOM页签视图. 注意:关联对象的属性列出现在右边,在关系属性列之后。并且, 零部件按数量排序, 因为在关系对象类的属性中该属性的序号优先级较高。
下面为网格显示设置为Intermix时的BOM页签视图。列完全按照每个属性定义的序号的顺序来排列。行的显示顺序完全由"排序"属性决定。行先根据Name排序,因为它的排序值为10,然后是Quantity,它的排序值为15 ,最后是Part Number, 它的排序值为2。
|
仅选取 | 在关系网格中创建相关对象时,只能从已有相关对象实例中选择。 |
仅创建 | 在关系网格中创建相关对象时,只能创建相关对象的新实例。 |
选取& 创建 | 在关系网格中创建相关对象时, 既可以从已有相关对象的实例中选择, 也可创建相关对象的新实例。 |
必需 |
选中时,源对象的关系页签下拉框中,无对象选项不显示。因此,当从源对象实例中创建关系时,只有两个选择:选择对象或新建对象,每种选择都要求必须输入相关对象。
|
打开相关窗体 | 如果选中,当从关系网格创建关联对象时,如果是创建关联对象的新实例,则将自动打开关联对象的编辑窗体。若不选中,则只能从属性列中输入数据,或者手动从右键弹出菜单中打开窗体。 |
拷贝权限 |
当创建关联对象选中时,此选项适用。它管理以下情况:一个Part的实例叫做Part1,它的BOM中存在一个Bracket实例,叫做Bracket1。用户复制并粘贴Bracket1到Part的另一个实例,Part2时,如果BOM关系类的创建关联对象设置为true,于是,根据Bracket1复制Bracket的一个实例,Bracket1副本。
如果原Bracket1实例设置了私有权限,用户根据该选项决定是否复制指定权限: |
创建关联对象 |
此选项当复制或粘贴关系时适用。我们用一个包含名为Bracket的BOM信息的Part组件举例说明。如果复制Bracket并粘贴至另一个Part的BOM中,下列选项将生效: |
3. 属性值填写完毕,下一步就是在页签中添加信息:
a. 网格事件-如果希望触发网格事件运行客户端方法,例如:选择行,插入行,删除行,可以在此处设置方法。如果你希望第一次创建关系(OnInsertRow)的时候,自动把一些数据的填充到关系中,你就可能需要考虑使用这种方法。关于如何书写客户端方法和如何在页签中设置属性,请参考Aras高级编程培训。
b. 关系查看-有时候当在源对象或是父对象中点击关系页签时,可能不希望看到基本的关系网格。你可能希望看到一个web页面,或是配置型的网格。你可以这个页签下进行设置,并且,这些设置基于身份的,所以不同的用户可能被指向不同的页面或是网格。下面为进程计划PFD中使用页面代替基础关系单元格的示例:
让我们看一个这个页签的列属性:
i. 名称—视图的有效身份名称
ii. 起始页面—http://web路径将会显示在这里(the http:// path to the web page to be displayed)
iii. 参数—希望传递给网页输入值
iv. 网格—为视图设计的可配置网格的引用(从选择对话框中选择)
c. 排斥:有些时候关系可能互相排斥。例如:你可能有一个零部件关系叫做BOM,和另一个零部件关系叫做供应商。但是,某个零部件也可以在室内制造,在这种情况下可能需要一个BOM页签,或者从供应商处购买(这种情况下只需要供应商页签)。所以,在排斥页签可以指定一系列相互排斥的关系列表。在此例中,关系类型BOMRel,可在排斥页签下指定VendorsRel。
d. 隐藏-当选中时,这个选项将会在所有源对象实例中隐藏该关系页签。例如,如果我们编辑BOM关系,在隐藏页签下选择隐藏,BOM页签将会在所有的零部件实例中被隐藏。
注意下面的图片,这是BOM标签页。
修改关系对象类
先前章节已提到过,当源对象保存时,一个对象会被自动创建,它就是关系对象类。它是一个标准的对象类,除了这些关系类属性会被设置为True。就像一个标准的对象类一样,它可以创建属性,事件和其他关系。这些都属于复杂数据模型部分,但是不属于本手册的范畴。
在本例中,我们创建一个从源对象类 HousePlanner到关联对象类 Contractor的关系,命名为ContractorRel.。下面,我们详细了解ContractorRel对象类。
编辑关系对象类的属性:
1. 点击TOC的系统管理文件夹,选择对象类,搜索ContractorRel。然后打开编辑,界面如下:
注意上半部分属性为系统默认设置。
a. Use Src Access -这意思是关系本身,而不是关联对象,继承父项或是源对象的权限和canAdd行为
b. 关系类 –当前对象是否为是关系结构,如果这个属性设置为ture,则表示是关系类。
c. Allow Private Permissions -允许私有权限
2. 通常,对每个关系,我们需要为关系本身添加一些属性。例如,对于零部件,在它的BOM关系中有一个属性叫做数量。这个属性是设置在关系上的,因为它只在源对象和关联对象之间的关系中才有意义。在我们的例子ContractorRel中,同样增加一些关系属性,如下:
a. 添加一个每周工时属性:这个属性值标示特定的承包商每周工作多少工时。
b. 增加一个属性叫做支付比例:这个值随每个承包商和任务而变化。换句话说,相同的承包商对于两样不同的任务可能给予不同的支付比例,因为不同的水平。
c. 确认新增属性的Hidden2的关系中隐藏属性没有被勾选。我们希望这两个属性在关系网格中显示。同样,不要点选任何系统属性的关系中隐藏属性,如果你想在关系单元格中显示这些属性。
3. 点击工具栏“保存 解锁并关闭”图标。
4. 创建一个HouseKeeper的实例,添加一些contractors,如下:
注意关联对象属性都在左边显示,这是在关系类中的默认设置,其次是关系属性。
创建一个标准的独立的关系类型
另一个创建关系的方法是在关系类中直接创建。当把所有对象类做为源对象创建关系时,这种方法是必需的。也就是说,当你想要在系统中给所有的对象类添加某些数据,例如,历史记录。这个已经在Innovator中配置好了,但是在这里它可以做为一个很好的范例。给所有对象添加历史记录,你需要创建一个没有源对象的关系类型,因为它将所有的对象类做为源对象。
创建一个关系类型
1. 点击TOC中的系统管理文件夹,选择关系类, 创建一个新的关系类;
2. 不设置源对象类,但是设置相关对象类为 History;
3. 按照自己的需求设置其他属性;
4. “保存”关系类对象;
5. 创建任意对象的一个实例你将会看到History页签。但是,如果选中“在所有页面隐藏”复选框, History要求将不会出现在任何对象中,但是关系依然存在。
如果你创建了一个关系类并选择了一个源对象类和关联对象类。它与“定义关系”章节描述的创建关系的过程完全一致。当保存关系类时,关系对象类会被系统自动创建,所有指定的源实例都会获得一个新页签。
关系VS属性
在数据建模一样的情况下,有很多方法去做同一件事情。有一些可能比其他的更有效率,有些可能更灵活。例如你想要通过对象1访问对象2的一个属性。一个方式是创建对象类1和对象类2之间的关系,然后设置所有必须的属性访问权限。另外一种方式是在对象类1定义中创建一个Foreign属性,引用对象2的需要的属性(参考Foreign数据类型)。这里有关于创建关系和使用Foreign 属性的比较:
1. 关系有更大的灵活性,允许访问超过多个属性值
2. 关系能够让一个对象1的实例关联多个对象2的实例
3. Foreign属性比关系更加有效,因为不需要在数据库增加2张附加表单
关系类型对象行为
在关系类型中,有一个定义的属性是行为。虽然只有两个选项:Float和Fixed,但是很多变化都取决于这个设置。让我们探讨一下其中的一些变化。在下图中我们将会使用父项和子项关联到对象。另一种理解这些对象的方法是:父项=源对象, 子项=关联对象。数字1和2是版本号,所以Parent1是源对象的第一个版本。
第一个实例就是Parent1连接到Child1, 然后 Parent1衍生出新版本Parent2。然后 Child1版本更新变成Child2。下面过程显示了关系的连接结果。
第二个Float案例可能产生这样一个疑问:如果行为是“Float”,为什么在Child2创建后,Paren1没有指定到Child2?根据“Float”行为定义,难道不是父项指向子项的最新版本吗?这些问题需要根据父项的版本规则来回答。为了保护配置信息,当父项换版时,它的先前版本仍将设置为“固定的”行为。换句话说:当父项换版时,它的先前版本将永远停留于配置。在上面这个案例中,Parent的第一个版本连接到Child1。当Parent先换版时,Parent1立即”冻结”指向Child1的当前配置。当然,Parent2将指向Child1,因为它是Child的最新版本。但是,由于定义了“浮动”行为,一旦Child换版,Child2被创建,Parent2将打破与Child1的绑定指向Child2。
下一个案例与前面相似, Child1在创建时已经关联到Parent1。如果是Child先换版,产生Child2。之后,Parent换版变成Parent2。下面是关系行为表:
在这个案例中,大家可能对“Fixed”行为存在疑问。为什么行为是“Fixed”,Parent2却关联到Child2?这是因为另外一个规则。当父项的一个新版本被创建,它自动与子项的最新版本关联。因此,如果一个更新的子项已经存在,即使行为被定义为“Fixed”,父项仍将自动关联到最新版本上。
另外两个行为---严格固定(Hard Fixed)和严格浮动(Hard Float)只在与生命周期设置结合时发挥作用。所以,我们将探讨在生命周期下的这些对象的行为。关于生命周期是怎样深入的影响可换版关联对象行为,请参阅“对象行为”介绍,