数据线与儿童和孙子的对象

时间:2017-07-28 19:30:36

标签: c# linq

我有一些以这种形式出现的数据:

+---------+---------+--------------+---------------------+
| Group 1 | Child 1 | Grandchild 1 | Greatgrandchild 1  |
| Group 1 | Child 1 | Grandchild 1 | Greatgrandchild 2  |
| Group 1 | Child 1 | Grandchild 2 | Greatgrandchild 3  |
| Group 1 | Child 1 | Grandchild 2 | Greatgrandchild 4  |
| Group 1 | Child 2 | Grandchild 3 | Greatgrandchild 5  |
| Group 1 | Child 2 | Grandchild 3 | Greatgrandchild 6  |
| Group 1 | Child 2 | Grandchild 3 | Greatgrandchild 7  |
| Group 1 | Child 2 | Grandchild 4 | Greatgrandchild 8  |
| Group 1 | Child 2 | Grandchild 4 | Greatgrandchild 9  |
| Group 2 | Child 3 | Grandchild 5 | Greatgrandchild 10 |
| Group 2 | Child 3 | Grandchild 5 | Greatgrandchild 11 |
| Group 2 | Child 3 | Grandchild 6 | Greatgrandchild 12 |
| Group 2 | Child 3 | Grandchild 6 | Greatgrandchild 13 |
| Group 2 | Child 4 | Grandchild 7 | Greatgrandchild 14 |
| Group 2 | Child 4 | Grandchild 7 | Greatgrandchild 15 |
| Group 2 | Child 4 | Grandchild 8 | Greatgrandchild 16 |
| Group 2 | Child 4 | Grandchild 8 | Greatgrandchild 17 |
| Group 2 | Child 4 | Grandchild 8 | Greatgrandchild 18 |
+---------+---------+--------------+---------------------+

我希望它将这些数据转换为带孩子的POCO:

+-List<Group>
  +-List<Child>
    +-List<Grandchild>
      +-List<Greatgrandchild>

然后我可以这样写:

foreach(var group in Groups)
{
    foreach(var child in group.Childs)
    {
        foreach(var grandChild in child.GrandChilds)
        {
            foreach(var greatGrandChild in grandChild.GreatGrandChilds)
            {
            }
        }
    }
}

我正在使用MVC,我想我可以使用LINQ来实现这一点。

我能够使用某些GroupBy'ing来强制执行此操作:

        var sb = new StringBuilder();

        foreach (var courses in query.GroupBy(c => c.courseInfo))
        {
            foreach (var course in courses)
            {
                sb.AppendLine(course.courseInfo);

                foreach (var semesters in courses.Where(c => c == course).GroupBy(s => s.semester_name))
                {
                    foreach (var semester in semesters)
                    {
                        sb.AppendLine(semester.semester_name);

                        foreach (var quizzes in semesters.Where(s => s == semester).GroupBy(q => q.quiz_name))
                        {
                            foreach (var quiz in quizzes)
                            {
                                sb.AppendLine(quiz.quiz_name);

                                foreach (var student in quizzes.Where(q => q == quiz))
                                {
                                    sb.AppendLine(student.last_name);
                                }
                            }
                        }
                    }
                }
            }
        }

        var results = sb.ToString();

我能够使用上面的代码构建一个字符串,并且可能构建我的类,但这显然不是一个“好”的方法。

1 个答案:

答案 0 :(得分:4)

这会让你走近:

var data = new List<Data>()
{
new Data(){Group="1", Child="1", Grandchild="1", Greatgrandchild="1"},
new Data(){Group="1", Child="1", Grandchild="1", Greatgrandchild="2"},
new Data(){Group="1", Child="1", Grandchild="2", Greatgrandchild="3"},
new Data(){Group="1", Child="1", Grandchild="2", Greatgrandchild="4"},
new Data(){Group="1", Child="2", Grandchild="3", Greatgrandchild="5"},
new Data(){Group="1", Child="2", Grandchild="3", Greatgrandchild="6"},
new Data(){Group="1", Child="2", Grandchild="4", Greatgrandchild="7"},
new Data(){Group="1", Child="2", Grandchild="4", Greatgrandchild="8"},
new Data(){Group="1", Child="2", Grandchild="5", Greatgrandchild="9"},
new Data(){Group="2", Child="3", Grandchild="5", Greatgrandchild="10"},
new Data(){Group="2", Child="3", Grandchild="6", Greatgrandchild="11"},
new Data(){Group="2", Child="3", Grandchild="6", Greatgrandchild="12"},
new Data(){Group="2", Child="3", Grandchild="7", Greatgrandchild="13"},
new Data(){Group="2", Child="4", Grandchild="7", Greatgrandchild="14"},
new Data(){Group="2", Child="4", Grandchild="8", Greatgrandchild="15"},
new Data(){Group="2", Child="4", Grandchild="8", Greatgrandchild="16"},
new Data(){Group="2", Child="4", Grandchild="9", Greatgrandchild="17"},
new Data(){Group="2", Child="4", Grandchild="9", Greatgrandchild="18"},
};

var result = data.GroupBy(d => d.Group).Select(d => new
{
    Group = d.Key,
    Childs = d.GroupBy(d2 => d2.Child).Select(d2 => new
    {
        Group = d2.Key,
        GrandChilds = d2.GroupBy(d3 => d3.Grandchild).Select(d3 => new
        {
            Group = d3.Key,
            GreatGrandchilds = d3.Select(d4 => d4.Greatgrandchild)
        })
    })
});

在LINQPad中运行会产生这种结构(我只扩展了其中一行,以便图像适合):

enter image description here

要一直到你想要的地方,你需要创建表示每个“生成”的类,并返回该类的实例,而不是像我的例子那样返回一个新的匿名类型。