Property 设计与验证
Property 描述 Item 的一个数据值。它会影响 AML 名称、验证、查询、表单控件和可能的数据库存储,但这些层不能混为一谈:创建 Property 不等于创建表单字段,界面只读也不等于服务器禁止修改。
本章继续使用 第一个 ItemType 中的 acme_equipment,加入型号、投产日期和设备类型三个属性。
核验基线
- 配置概念以 R31 原厂配置培训为基线。
- AML 验证方式以 R35 Programmer's Guide 为基线。
- 不使用“每个 ItemType 固定有 23 个系统属性”或“某类型必定映射为某个 SQL 类型”一类未经目标 Release 验证的结论。
先做字段设计
| Name | Label | Data Type | 约束 |
|---|---|---|---|
acme_model | 型号 | String | 最大长度按真实业务上限设置 |
acme_commissioned_on | 投产日期 | Date | 可空 |
acme_equipment_type | 设备类型 | List | 引用受控 List |
命名时遵守三条规则:
- 内部 Name 一经被 AML、Method、报表使用,就应视为接口契约。
- Label 可以本地化,不应被代码当作字段名。
- 自定义定义使用统一前缀,避免与 OOTB 或后续升级新增内容冲突。
第 1 步:创建 String 属性
在 acme_equipment 的 Properties 页签中新建 acme_model:
- Data Type 选择 String。
- Length 按真实输入上限设置,并为未来合理增长留余量。
- 仅在业务确实要求时设置 Required 或 Unique。
- 保存 ItemType。
- 将字段放到目标 Form,并测试输入边界。
不要用数据库类型反推平台规则
不同 Release、数据库层实现或迁移路径可能产生不同物理定义。文档和代码应依赖 Property 元数据与平台 API,而不是假定 String 一定是 nchar(n)。
第 2 步:创建 Date 属性
创建 acme_commissioned_on,Data Type 选择 Date。日期显示格式和实际传输值是两件事:
- 表单和客户端按用户 Locale 显示。
- AML/IOM 应使用服务器接受的中性格式。
- 跨系统集成必须明确时区和“日期”是否包含时间语义。
用 AML 查询时,不要把本地化显示文本直接拼进条件:
<Item type="acme_equipment" action="get"
select="item_number,acme_commissioned_on">
<acme_commissioned_on condition="is not null" />
</Item>第 3 步:创建受控 List
- 创建或复用一个 List,例如
acme_equipment_type。 - 为每个值设置稳定的内部 Value 和面向用户的 Label。
- 在 Property 上选择对应的 List 数据源。
- 在 Form 上确认渲染为合适的选择控件。
- 通过 AML 查询保存结果,确认数据库保存的是预期 Value,而不是依赖显示 Label。
List 适合有限、稳定的枚举。若选项本身有权限、生命周期、属性或大量记录,应建独立 ItemType,再使用 Item 类型 Property。
常用 Property 类型怎么选
| 需求 | 优先考虑 | 注意事项 |
|---|---|---|
| 短文本、编码 | String | 明确长度与大小写规则 |
| 长说明 | Text / Formatted Text | 富文本要考虑内容净化与输出场景 |
| 整数或小数 | Integer / Decimal / Float | 金额、精确计量通常不应随意用 Float |
| 日期或时间 | Date | 明确 Locale、时区与空值 |
| 是/否 | Boolean | 约定空值与 false 是否不同 |
| 有限枚举 | List | 代码使用 Value,不使用翻译后的 Label |
| 引用单个业务对象 | Item | 配置 Data Source,并验证目标权限 |
| 自动编号 | Sequence | 并发与补号策略由平台/业务定义 |
| 从引用 Item 展示字段 | Foreign | 先有 Item Property,再选择其目标 Property |
| 扩展分类动态字段 | xProperty(独立元数据机制,并非标准 Property 的 Data Type) | 参见 扩展分类 |
这不是所有 Release 的完整 Data Type 清单。请以目标系统 Property 编辑器和同版本帮助文档为准。
Item Property 与 Foreign Property
假设设备需要引用一个制造商:
- 创建
acme_manufacturer,Data Type 为 Item,Data Source 指向制造商 ItemType。 - 再创建
acme_manufacturer_code,类型为 Foreign。 - 将 Foreign Property 指向
acme_manufacturer所引用 Item 的编码属性。
Foreign 值用于展示关联对象的数据,不应被误解为一份可以独立编辑的副本。若业务要求“下单时冻结当时名称”,应创建普通快照属性并在明确事件中写入。
系统 Property
保存 ItemType 后,平台会管理一组与 ID、创建/修改审计、锁、权限、状态和版本相关的 Property。具体集合取决于 ItemType 配置与 Release,因此:
- 不删除或重定义不理解的系统 Property。
- 不把数量写死进升级脚本或检查脚本。
- 通过同版本环境的 ItemType 元数据确认实际集合。
- 使用公开含义,如
id、permission_id、locked_by_id,仍要结合对象是否版本化等配置。
Required、Unique 与 Default 的边界
Required
Required 表达数据约束,但仍要测试所有写入入口:Form、AML、导入和集成。客户端红色必填标记只是表现,服务器验证才是数据边界。
Unique
启用前先扫描已有数据和空值策略。不要假设在多个 Property 上勾选 Unique 会自动形成你想要的“组合唯一键”;组合业务键应按目标 Release 的支持方式设计并做并发测试。
Default Value
默认值只解决“新 Item 初始为什么值”,不能代替业务事件。验证复制、另存为、升版和 API 新增时是否都符合预期。
表单显示不是数据安全
Property 的 Hidden、控件 Disabled、条件隐藏只改变用户体验。攻击者或外部集成仍可能直接提交 AML。敏感字段应通过 Permission、服务器事件和业务规则保护。
参见 权限模型 和 代码样例中的表单只读边界。
用 AML 验证
新增一条测试数据:
<AML>
<Item type="acme_equipment" action="add">
<item_number>EQ-0002</item_number>
<name>装配工作站</name>
<acme_model>WS-20</acme_model>
<acme_commissioned_on>2026-08-13T00:00:00</acme_commissioned_on>
<acme_equipment_type>workstation</acme_equipment_type>
</Item>
</AML>随后只查询本章属性:
<AML>
<Item type="acme_equipment" action="get"
select="id,item_number,acme_model,acme_commissioned_on,acme_equipment_type">
<item_number>EQ-0002</item_number>
</Item>
</AML>预期结果:返回一条 Item;List 返回内部值;Date 结果可能由客户端按 Locale 再格式化。
Property 上线检查表
- [ ] Name 稳定、有前缀且未被现有接口占用
- [ ] Data Type 与业务语义匹配
- [ ] String 长度和 Decimal 精度经过边界测试
- [ ] Required、Unique、Default 在 UI 与 API 场景都测试过
- [ ] List 的 Value 与 Label 分离
- [ ] Item Property 的目标权限已测试
- [ ] Field 已放入正确 Form,且没有把 UI 控制当作授权
- [ ] 修改已有 Property 前已评估存量数据与包升级
修改已有 Property
缩短长度、改变类型、改内部名称或切换数据源都可能是破坏性变更。推荐流程:
- 导出存量数据分布和异常值报告。
- 在与生产同版本的副本上导入 Package。
- 验证迁移、回滚、搜索、Form 和集成。
- 对外部接口设置过渡期,不在同一次发布中悄悄改契约。
- 通过支持的 Package/配置机制交付,不直接
ALTER TABLE。
下一步
依据
- Aras Training, Configuring Solutions Student Guide Innovator R31, Property、Form 与 Extended Classification 单元
- Aras Innovator 35 Programmer's Guide
- Aras Documentation Library
