结构体与共享属性
一个属性里放几个字段的结构体和它的限制;一个定义、多个类型共用的共享属性。

本课目标
读完这一课,你将能够
- 写出结构体属性的字段,说出它的限制
- 判断该用结构体、多个属性,还是另一个对象类型
- 写出共享属性的定义,用到多个对象类型上,并说出共享的是什么
结构体:一个属性,几个字段
前面几种类型,一个属性只装一个值。客户的联系人却是「姓名加邮箱」两样东西,总是一起出现。这时可以用结构体(struct):一个属性里放几个有名字、有类型的字段。
{
"name": "contact",
"type": "struct",
"title": "Contact",
"structFields": [
{ "name": "name", "type": "string", "title": "Name" },
{ "name": "email", "type": "string", "title": "Email" }
]
}
读回来的值是一个对象:"contact": { "name": "Lena Zhou", "email": "lena@example.com" }。结构体有几条硬规则:
- 结构体里不能再放结构体。
- 字段只能是标量(
string、integer、long、short、byte、boolean、float、double、decimal、date、timestamp)或geopoint,不能是数组。 - 至少要有一个字段,AIDC 里最多 20 个。
- 结构体不能做主键或标题键。
- 结构体属性本身也可以是数组,也就是一组结构体。
比如供应商有多位联系人,就把 contact 写成结构体数组:type 写 array,arraySubType 写 struct,再给出 structFields。
结构体、多个属性,还是对象类型
| 结构体 | 独立的对象类型 | |
|---|---|---|
| 身份 | 没有自己的主键,是所属对象的一部分 | 有自己的主键,可以被单独找到 |
| 关系 | 不能连别的对象类型 | 可以连关系 |
| 历史 | 跟着所属对象的编辑历史走 | 每个对象各有编辑历史 |
| 例子 | customer.contact:姓名加邮箱 | orderLine:订单的每一行,各自关联产品 |
判断的办法:这几个字段有没有自己的身份,要不要连关系,要不要被单独找出来?三样都不要,用结构体;有一样要,就建成对象类型。
在 salesOrder 上放一个结构体数组,存每一行的 sku、数量、单价。想看某个产品卖了多少,得把所有订单翻一遍。
把订单行建成对象类型 orderLine,用关系连到订单和产品。每一行都能单独被找到、被改、被记录。
结构体的字段只有名字、类型、显示名和说明,没有单位、同义词,也不能单独设必填。只要其中任何一样用得到,就平铺成几个属性更合适;结构体留给总是作为一个整体出现的东西。
另一个常见的坑,是想在结构体里再套一层,比如给 contact 加一个有街道、城市两个字段的 address。这不允许:把街道、城市拉平成 contact 的字段,或者把地址建成独立的对象。
共享属性:一个定义,多处使用
示例工厂里,客户、订单、工单都有「负责人」ownerId,也都有「创建时间」createdAt。如果每个类型各写一遍,显示名、说明、同义词就会慢慢各写各的。共享属性(Shared Property)把这份定义写一次,让多个对象类型引用。
{
"kind": "sharedPropertyType",
"apiName": "ownerId",
"title": "Owner",
"description": "The person accountable for this record.",
"schema": {
"type": "string",
"synonyms": ["responsible", "accountable person"]
}
}
每个用到它的类型,在自己的 columns 里加一行。类型要和共享属性一致;属性自己没写的显示名、说明、单位、同义词、值类型和格式,取共享属性的,自己写了的优先。
{ "name": "ownerId", "type": "string", "sharedProperty": "ownerId" }
已经存在的属性也能事后接入:在它的定义里加上 sharedProperty,属性的名字和已有的数据都不变。接入前先确认类型一致。
共享的只有元数据,各类型的对象数据并不共享:客户的 ownerId 和工单的 ownerId 是两组值,只是共用一份定义。共享属性也是接口的零件,接口 Schedulable 的 dueAt 和 status 就由它承载,下一门课会讲。
共享属性的好处在修改时才显出来:给 ownerId 加一个同义词「责任人」,所有引用它的类型立刻读到新的元数据,不用逐个去改。反过来,它被很多类型共用,改类型或删除之前,要先查清有多少类型在用它。
下一节讲值类型:把取值的规则写进类型里。
要点
- 结构体在一个属性里放几个字段:字段只能是标量和
geopoint,不能嵌套,也不能是数组。 - 字段要有自己的身份、关系或历史,就建成对象类型,别用结构体。
- 共享属性把一份定义给多个对象类型用;共享的是元数据,不是数据。
- 属性自己写的元数据优先,没写的取共享属性的。
练一练
联系人、地址与负责人
示例工厂的供应商需要联系人,客户需要收货地址,好几类对象都要负责人。
给 supplier 写一个 contact 结构体:姓名、邮箱、电话,再写出一个取值。
客户有收货地址(街道、城市、邮编),而且每个客户可能有多个地址。用结构体、结构体数组还是对象类型?写出理由。
写一个共享属性 createdAt(timestamp),用到 salesOrder 和 workOrder 上,再运行 aidc semantic shared-properties 看看。
小测
选一个答案,马上看解析。
Q1想在 contact 结构体里再放一个 address(街道、城市)。怎么办?
结构体不能嵌套,字段也不能是数组。要么拉平,要么把地址当作有自己身份的东西,建成对象类型。
Q2customer、salesOrder、workOrder 都引用了共享属性 ownerId。哪些东西是共享的?
共享属性共享的是属性的定义和元数据。客户的负责人和工单的负责人是各自的值。
Q3每张订单有很多行,每行有 sku、数量、单价,还要能各自连到产品。怎么建?
结构体不能连关系。订单行要连产品,要能被单独找到和修改,就该是对象类型。