首页 > 解决方案 > 使用 LinQ 创建分层 JSON Http 响应结构

问题描述

我正在尝试从 ASP.NET webAPI 获得嵌套的分层 JSON 响应,其中定义了基于 SQL 表的平面模型。

我是 ASP.NET WebAPI 的新手。我有一个 MVC ASP.NET 项目,其中定义了一个程序集模型类。每个程序集都可以是另一个程序集的子项,理论上具有无限子项和 childrenOfchildren。

链接到 SQL 表的装配模型类定义如下:

Int Id
String Name
Int ParentId

我需要执行 Http GET 来检索父子层次结构。

现在我在程序集控制器类中有以下功能:

[Route("api/Assembly/GetTree/{id}")]
[HttpGet]
public IEnumerable<Assembly> GetTree(int id)
{
    var assemblies = db.Assemblies.Where(x => x.ParentId == id || x.Id == id).ToList();
    var child = assemblies.AsEnumerable().Union(db.Assemblies.AsEnumerable().Where(x => x.ParentId == id).SelectMany(y => GetParent(y.Id))).ToList();

    return child;
}

问题(我认为)是“联合”返回给我一个平坦的 JSON 响应。

db.Assembies 是从 db 自动生成的 db 上下文模型类程序集的实例,定义如下:

public partial class Assembly
    {
        public Assembly(){}

        public int Id { get; set; }
        public string Name { get; set; }
        public int ParentId { get; set; }
    }

预期的结果应该是这样的:

[
    {
        Id: '1',
        Name: 'Assembly1',
        ParentId: '0'
        children: [
            {
                Id: '2',
                Name: 'Assembly1.1',
                ParentId: '1',
            },
            {
                Id: '3',
                Name: 'Assembly1.2',
                ParentId: '1',
            },
        ]
      }, 
      {
        Id: '4',
        Name: 'Assembly2',
        ParentId: '0'
        children: [
            {
                Id: '5',
                Name: 'Assembly2.1',
                ParentId: '4',
                children: [
                    {
                        Id: '6',
                        Name: 'Assembly2.1.1',
                        ParentId: '5',
                    },
                    {
                        Id: '7',
                        Name: 'Assembly2.1.2',
                        ParentId: '5',
                    },
                ]
            },  
            {
                Id: '8',
                Name: 'Assembly2.2',
                ParentId: '4'
                children: [
                    {
                        Id: '9',
                        Name: 'Assembly2.2.1',
                        ParentId: '8',
                    },
                    {
                        Id: '10',
                        Name: 'Assembly2.2.2',
                        ParentId: '8',
                    },
                ]
            },
        ]
    },
]

我怎样才能将组件放在其他组件中?

标签: c#sqllinqasp.net-web-api

解决方案


我认为主要问题是子节点从父节点不可见。所以序列化父节点,只会给父节点。但是,如果父级存储了所有子级,那么序列化逻辑将能够递归所有依赖的数据并为您提供您正在寻找的嵌套层次结构。

类似于这样的东西:

void Main()
{
    var grandChild1 = new Node() { Name = "GrandChild1" };  
    var child1 = new Node() { Name = "Child1", Children = new List<Node> {grandChild1} };
    var child2 = new Node() { Name = "Child2" };    
    var root = new Node() { Name = "Root", Children = new List<Node> {child1, child2} };

    var serialized = JsonConvert.SerializeObject(root);

    Console.WriteLine(serialized);
}

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

这将给出以下输出:

{
    "Name": "Root",
    "Children": [{
            "Name": "Child1",
            "Children": [{
                    "Name": "GrandChild1",
                    "Children": null
                }
            ]
        }, {
            "Name": "Child2",
            "Children": null
        }
    ]
}

推荐阅读