如何在 ocl 中执行此操作?

How to possibly do this in ocl?

我有以下架构:

对于老板class,我需要所有做出最高价值销售的代理商的名字(类似于:foreach agent,select agent name if he has max(foreach command, total = total + price of the product * quantity from command). 我如何在 OCL 中执行此操作?

如果您认为您处于模型的根部(没有特别的上下文)以便 select 20 第一个顶级代理:

Agent.allInstances()->sortedBy(- sale->collect(quantity*product.price)->sum())->subSequence(1, 20)

并且来自 Boss 个实例:

self.workers->sortedBy(- sale->collect(quantity*product.price)->sum())->subSequence(1, 20)

请求背后的想法是(第一个):

  1. 获取所有代理(Agent.allInstances()
  2. 对它们进行排序 (...->sortedBy(...))
  3. 使用他们的销售额总和 (... sale->...->sum())
  4. a "sale" 由 mult 定义。参考产品价格的数量 (quantity*product.price)
  5. 对于每次销售,计算这些东西 (...sale->collect(...))
  6. 根据这个最终结果(sum 一个),反转结果使顶部在第一位(... - sale->collect()->sum()...
  7. 从这个最终列表中,select 一个子序列 (...->subSequence(1,X))

编辑>

有关关联 class 导航的详细信息(来自 "OCL Specification",第 21 页)

To specify navigation to association classes (Job and Marriage in the example), OCL uses a dot and the name of the association class

遵循早期版本的规范,Association Class名称据说是小写的,在后来的版本中,名称保持不变。

EDIT2>

为了获得更高的分数以及获得最高分数的代理人姓名:

let score : Integer = -(self.workers->collect(sale->collect(quantity*product.price)->sum())->sortedBy(i | -i)->first())
in self.workers->select(sale->collect(quantity*product.price)->sum() = score).name

先让select得分高的(收集所有得分,倒序排列,select第一个元素),然后select所有有a的工人分数等于先前计算的分数。