使用LinQ创建分层的JSON Http响应结构

时间:2019-05-09 08:10:57

标签: c# sql linq asp.net-web-api

我正在尝试从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上下文模型类程序集的实例:

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',
                    },
                ]
            },
        ]
    },
]

我如何将一个组件放入另一个内部?

1 个答案:

答案 0 :(得分:0)

我认为主要问题是从父节点看不到子节点。因此,序列化父级,将只给出父级节点。但是,如果父级存储了所有子级,则序列化逻辑将能够遍历所有依赖的数据,并为您提供所需的嵌套层次结构。

与此类似:

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
        }
    ]
}