ATL辅助代码报错原因排查:Collections do not have properties问题
问题原因分析与修复方案
那个错误提示已经把问题点得很清楚了:
org.eclipse.m2m.atl.engine.emfvm.VMException: Collections do not have properties, use ->collect()
核心问题出在哪?
你的Test!Test元模型里的act属性应该是多值关联(也就是一个Test对应多个Action实例)。当你写n.act.id的时候,你是在试图给一整个Action集合直接访问id属性——但集合本身根本没有id这个属性啊!只有集合里的单个Action实例才有id,OCL不允许直接对集合调用实例级别的属性,必须先用->collect()遍历集合里的每个元素才行。
修正后的辅助代码
把你的helper方法改成下面这样就能解决问题了:
helper def: actionsId: Integer = Test!Test.allInstances() ->select(i | i.md.user='admin') ->collect(n | n.act->collect(a | a.id.toInteger())) ->flatten() ->sum();
为什么要这么改?
- 替换
n.act.id为n.act->collect(a | a.id.toInteger()):这一步是针对每个Test关联的所有Action集合,逐个取出每个Action的id并转成Integer类型,而不是试图给整个集合要id。 - 增加
->flatten():前面的collect会返回嵌套的集合(每个Test对应一个Action id的小集合),flatten()能把这些嵌套集合拆成一个扁平的整数列表,这样sum()才能正确计算所有id的总和。
从你的转换规则也能印证这点
看你Testset2Testcase规则里的act <- thisModule.resolveTemp(s.act,'a'),resolveTemp一般是用来处理多值关联的转换逻辑的,这也说明Test!Test.act确实是多值属性,必须用集合操作来处理它。
内容的提问来源于stack exchange,提问作者Mikel
相关产品推荐
相关产品推荐

