eclipseEMF-如何以编程方式从模型中删除实例



我已经创建了名为WFG.ecore的元模型。

使用ATL,我成功地转换了WFG模型中的bpmn2文件。ATL转换提供给对象WorkFlow,即WFG中所有其他对象的容器。

现在我想用Java编程修改对象WorkFlow,但我做不到。

如何从对象实例的容器中删除对象实例,以及从所有引用中删除对象?

下面是一个实例的例子

            gateways
           +--------->+----------+
           |          |Gateway_1 |
           ♦          +----------+
+-----------+              ^
|WorkFlow_1 |              | nextGateway 0..1
+-----------+              |
           ♦           +---------+
           |           | Node_1  |
           +---------->+---------+
           nodes

我想删除实例Gateway_1,这样它就不再包含在WorkFlow_1中,这样Node_1.getNextGateway->null。我试着去做WorkFlow_1.getGateways().remove(Gateway_1)但不工作

简单的答案是使用EcoreUtil.delete()Delete命令。这两者都将EObject从其容器中移除,并移除(即空出(任何交叉引用。不过,总的来说,你不想这样做,原因如下:

  1. 子引用。尽管EcoreUtil.delete(Gateway_1)将从其容器和Node_1引用中删除Gateway_1,但它不会删除对Gateway_1子级的任何交叉引用,即使它们也将从容器中删除。因此,最终可能会出现对Gateway_1的子对象的不存在对象的悬空引用。

  2. 性能。没有可靠的方法可以有效地找到交叉引用。这意味着将检查模型中的每个EObject,以查看它是否有对Gateway_1的交叉引用,从而可以删除交叉引用。这使得EcoreUtil.delete()成为O(n(操作,其中n是模型中EObjects的数量。

最好的解决方案是双向引用和引用映射的某种组合。Gateway_1应该知道谁在交叉引用它,或者该信息应该可以在其他地方访问。通过这种方式,您可以以高效和完整的方式显式地删除对Gateway_1的所有引用。

这个答案紧跟着Maximilian Koegel和Jonas Helming的这篇博客文章,EMF Dos and Don’ts#11。

顺便说一下,EcoreUtil.remove()不执行交叉引用删除,它只是从容器中删除EObject。

DeleteCommand.create(editingDomain, Collections.singleton(Gateway_1));
editingDomain.getCommandStack().execute(command);

对于Node_1:

Node_1.setNextGateway(null);

相关内容

  • 没有找到相关文章

最新更新