Files

71 lines
2.5 KiB
C#
Raw Permalink Normal View History

2025-09-16 16:06:41 +08:00
namespace Szmedi.RevitToolkit.Approval.Models
{
/// <summary>
/// 建筑工程代表实体继承树中的一个节点。
/// </summary>
public class ArchiNode
{
/// <summary>
/// 当前节点所代表的实体定义数据。
/// </summary>
public EntityDefinition Data { get; set; }
/// <summary>
/// 当前节点的直接子节点列表。
/// </summary>
public List<ArchiNode> Children { get; set; }
public ArchiNode()
{
Children = [];
}
public override string ToString() => $"Node: {Data.Name}, Children: {Children.Count}";
}
/// <summary>
/// 一个静态工具类,用于从实体定义列表中构建继承树。
/// </summary>
public static class EntityTreeBuilder
{
/// <summary>
/// 根据实体定义列表中的继承关系构建一个或多个树。
/// </summary>
/// <param name="definitions">从MvdParser解析出的实体定义列表。</param>
/// <returns>一个包含所有根节点(没有父类的实体)的列表。</returns>
public static List<ArchiNode> Build(List<EntityDefinition> definitions)
{
if (definitions == null || !definitions.Any())
{
return [];
}
// 步骤 1: 创建一个名称到节点的映射,方便快速查找父节点。
var nodeMap = definitions.ToDictionary(
def => def.Name, // Key 是实体名称
def => new ArchiNode { Data = def } // DefaultValue 是新创建的节点
);
var rootNodes = new List<ArchiNode>();
// 步骤 2: 遍历所有节点,将它们连接到各自的父节点上。
foreach (var node in nodeMap.Values)
{
// 检查实体是否有父类,并且该父类存在于我们的映射中。
if (!string.IsNullOrEmpty(node.Data.InheritsFrom) && nodeMap.TryGetValue(node.Data.InheritsFrom, out ArchiNode parentNode))
{
// 如果找到了父节点,则将当前节点加到父节点的子集列表中。
parentNode.Children.Add(node);
}
else
{
// 如果没有父类或找不到父类,则认为它是一个根节点。
rootNodes.Add(node);
}
}
return rootNodes;
}
}
}