ASP.NET Core API中的递归映射-树结构

时间:2020-05-24 13:04:39

标签: asp.net asp.net-core asp.net-web-api

我正在制作树形结构。结果,我想得到这样的结构:

[
  {
    name: 'node1',
    subNodes: [
      {
        name: 'node1-1',
        subNodes: [],
      },
      {
        name: 'node1-2',
        subNodes: [],
      },
    ],
  },
  {
    name: 'node2',
    subNodes: [],
  },
  {
    name: 'node3',
    subNodes: [
      {
        name: 'node3-1',
        subNodes: [
          {
            name: 'node3-1-1',
            subNodes: [],
          },
          {
            name: 'node3-1-2',
            subNodes: [],
          },
        ],
      },
      {
        name: 'node3-2',
        subNodes: [],
      }
    ],
  },
];

为此,我创建了一个Api端点:

        [HttpGet]
        public async Task<IActionResult> GetTree()
        {
            var tree = await _treeService.GetTreeAsync();

            return Ok(tree);
        }

_treeService方法:

        public async Task<IEnumerable<NodeModel>> GetTreeAsync()
        {
            var tree = await _context.Nodes.ToListAsync();

            return _mapper.Map<IEnumerable<NodeModel>>(tree);
        }

这里是映射:

CreateMap<Node, NodeModel>();

节点正在映射到NodeModel:

    public class NodeModel
    {
        public string Name { get; set; }
        public List<Node> SubNodes { get; set; }
    }

和节点实体:

    public class Node
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int NodeId { get; private set; }
        public string Name { get; set; }
        public int? ParentNodeId { get; set; }
        [ForeignKey("ParentNodeId")]
        public Node ParentNode { get; set; }
        public List<Node> SubNodes { get; set; }
        public List<Leaf> SubLeaves { get; set; }
        public Node()
        {
            SubNodes = new List<Node>();
            SubLeaves = new List<Leaf>();
        }
    }

但是结果是:

[
    {
        "name": "Node1",
        "subNodes": [
            {
                "nodeId": 18,
                "name": "Node1_SubNode1",
                "parentNodeId": 17,
                "parentNode": {
                    "nodeId": 17,
                    "name": "Node1",
                    "parentNodeId": null,
                    "parentNode": null,
                    "subNodes": [
                        {
                            "nodeId": 19,
                            "name": "Node1_SubNode2",
                            "parentNodeId": 17,
                            "subNodes": [],
                            "subLeaves": []
                        },
                        {
                            "nodeId": 20,
                            "name": "Node1_SubNode3",
                            "parentNodeId": 17,
                            "subNodes": [],
                            "subLeaves": []
                        }
                    ],
                    "subLeaves": []
                },
                "subNodes": [],
                "subLeaves": []
            },
            {
                "nodeId": 19,
                "name": "Node1_SubNode2",
                "parentNodeId": 17,
                "parentNode": {
                    "nodeId": 17,
                    "name": "Node1",
                    "parentNodeId": null,
                    "parentNode": null,
                    "subNodes": [
                        {
                            "nodeId": 18,
                            "name": "Node1_SubNode1",
                            "parentNodeId": 17,
                            "subNodes": [],
                            "subLeaves": []
                        },
                        {
                            "nodeId": 20,
                            "name": "Node1_SubNode3",
                            "parentNodeId": 17,
                            "subNodes": [],
                            "subLeaves": []
                        }
                    ],
                    "subLeaves": []
                },
                "subNodes": [],
                "subLeaves": []
            },
            {
                "nodeId": 20,
                "name": "Node1_SubNode3",
                "parentNodeId": 17,
                "parentNode": {
                    "nodeId": 17,
                    "name": "Node1",
                    "parentNodeId": null,
                    "parentNode": null,
                    "subNodes": [
                        {
                            "nodeId": 18,
                            "name": "Node1_SubNode1",
                            "parentNodeId": 17,
                            "subNodes": [],
                            "subLeaves": []
                        },
                        {
                            "nodeId": 19,
                            "name": "Node1_SubNode2",
                            "parentNodeId": 17,
                            "subNodes": [],
                            "subLeaves": []
                        }
                    ],
                    "subLeaves": []
                },
                "subNodes": [],
                "subLeaves": []
            }
        ]
    },
    {
        "name": "Node1_SubNode1",
        "subNodes": []
    },
    {
        "name": "Node1_SubNode2",
        "subNodes": []
    },
    {
        "name": "Node1_SubNode3",
        "subNodes": []
    }
]

我们可以看到,模型尚未完全映射,但是最后在同一行上显示。我该如何解决?

PS:对不起,我的英语

1 个答案:

答案 0 :(得分:1)

我建议您在NodeModel类中为SubNodes属性使用NodeModel类型。我的意思是

public class NodeModel {
    public string Name { get; set; }
    public List<NodeModel> SubNodes { get; set; } 
}

这样,您的模型类将仅具有那些应该与API使用者相关的属性。似乎正是您所需要的。