Enterprise Architect插件开发:部件分配关系查询及分配增删操作的C#实现咨询
解答Enterprise Architect插件的分配关系处理问题
针对你开发EA插件时遇到的这几个需求,我结合EA的官方API和底层数据结构,给你一步步拆解解决方案:
首先验证:分配关系的存储位置
你之前找t_object表是不对的——EA里的<<allocate>>关系属于连接器(Connector),不是独立的对象,它存储在t_connector表中,关键字段说明:
Connector_Type: 固定为"Abstraction"Stereotype: 固定为"allocate"(注意大小写,EA对构造型大小写敏感)Start_Object_ID: 分配关系的源部件ID(比如你说的部件A)End_Object_ID: 分配关系的目标部件ID(比如部件B、C)
⚠️ 特别提醒:除非特殊场景,优先用EA提供的官方API操作,不要直接读写数据库——直接操作可能破坏模型的一致性,比如EA的缓存、事务机制都会受影响。
1. 查询特定部件的被分配目标部件
通过EA.Element的Connectors集合筛选符合条件的连接器,就能拿到目标部件:
/// <summary> /// 获取指定部件的所有被分配目标部件 /// </summary> /// <param name="sourcePart">源部件</param> /// <returns>目标部件列表</returns> public List<EA.Element> GetAllocatedTargets(EA.Element sourcePart) { var targetParts = new List<EA.Element>(); if (sourcePart == null || sourcePart.Connectors.Count == 0) return targetParts; foreach (EA.Connector conn in sourcePart.Connectors) { // 筛选<<allocate>>关系:类型是Abstraction,构造型是allocate,且当前部件是源 if (conn.ConnectorType == "Abstraction" && conn.Stereotype == "allocate" && conn.ClientID == sourcePart.ElementID) // ClientID对应Start_Object_ID,是源端 { var targetElement = sourcePart.Repository.GetElementByID(conn.SupplierID); if (targetElement != null) targetParts.Add(targetElement); } } return targetParts; }
2. 删除分配关系的C#方法
找到对应的连接器后,调用Delete()方法即可,注意要先定位到正确的关系:
/// <summary> /// 删除源部件到目标部件的<<allocate>>关系 /// </summary> /// <param name="source">源部件</param> /// <param name="target">目标部件</param> /// <returns>是否删除成功</returns> public bool RemoveAllocateRelationship(EA.Element source, EA.Element target) { if (source == null || target == null) return false; foreach (EA.Connector conn in source.Connectors) { if (conn.ConnectorType == "Abstraction" && conn.Stereotype == "allocate" && conn.ClientID == source.ElementID && conn.SupplierID == target.ElementID) { // 删除连接器 source.Repository.DeleteConnector(conn.ConnectorID); // 刷新源部件的连接器集合 source.Refresh(); return true; } } // 未找到对应关系 return false; }
3. 添加分配关系的C#方法
通过Repository创建新的连接器,设置对应的类型和构造型:
/// <summary> /// 给源部件添加到目标部件的<<allocate>>关系 /// </summary> /// <param name="source">源部件(被分配的对象,比如部件T)</param> /// <param name="target">目标部件(接收分配的对象,比如部件B)</param> /// <returns>创建成功的连接器,失败返回null</returns> public EA.Connector AddAllocateRelationship(EA.Element source, EA.Element target) { if (source == null || target == null || source.Repository == null) return null; // 先检查是否已经存在该分配关系,避免重复创建 foreach (EA.Connector conn in source.Connectors) { if (conn.ConnectorType == "Abstraction" && conn.Stereotype == "allocate" && conn.ClientID == source.ElementID && conn.SupplierID == target.ElementID) { return conn; // 已存在,直接返回 } } // 创建新的连接器 EA.Connector newConn = source.Repository.GetNewConnector(); newConn.ConnectorType = "Abstraction"; newConn.Stereotype = "allocate"; // 设置源和目标:Client是源,Supplier是目标 newConn.ClientID = source.ElementID; newConn.SupplierID = target.ElementID; // 设置连接器的名称(可选,根据你的需求) newConn.Name = $"Allocate {source.Name} to {target.Name}"; // 保存连接器 newConn.Update(); // 刷新源和目标部件的连接器集合 source.Refresh(); target.Refresh(); return newConn; }
额外注意事项
- 操作前确保
EA.Repository对象是有效且已连接的; - EA的API对大小写敏感,比如
Stereotype必须是"allocate"(小写),不能写成"Allocate"; - 如果需要批量操作,记得用Repository的
EnableUIUpdates和BatchAppend方法提升性能; - 若必须直接操作数据库,除了
t_connector表,还要同步更新t_connectorproperties(如果有自定义属性),但强烈不推荐这种方式。
内容的提问来源于stack exchange,提问作者Ice
相关产品推荐
相关产品推荐

