Linq查询,使用单个数据表构建嵌套对象

时间:2015-06-24 16:08:33

标签: c# json angularjs linq nested

我有一个非常大的数据表,下面是它的快照:

Section         |SectionId |    Lesson                | LessonId  | Activity           |    Date    |     Time   | Score |  Duration
                |          |                          |           |                    |            |            |       |             
Functions       |   123    | Intro to Functions       | 6374      |  Activity Quiz 1   |  6/10/2014 |  18:55:00  |  80   |   5
Functions       |   123    | Intro to Functions       | 6374      |  Domain and Range  |  6/10/2014 |  19:33:00  |  0    |   36
Functions       |   123    | Intro to Functions       | 6374      |  Activity Quiz 2   |  6/10/2014 |  19:37:00  |  100  |   4
Linear Functions|   124    | Intro to Linear Functions| 6378      |  Authentic Task: 1 |  6/23/2014 |  13:54:00  |  0    |   0
Linear Functions|   124    | Intro to Linear Functions| 6378      |  Activity Quiz: 3  |  6/18/2014 |  14:12:00  |  80   |   4
Linear Functions|   124    | Intro to Linear Functions| 6378      |  Step Functions    |  6/18/2014 |  14:59:00  |  0    |   46

我有以下c#类:

    public class Section
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public List<Lesson> Lessons { get; set; }
    }

    public class Lesson
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public List<Activity> Activities { get; set; }
        public int SectionId { get; set; }
    }

    public class Activity
    {
        public string Name { get; set; }
        public string Date { get; set; }
        public string Time { get; set; }
        public int Score { get; set; }
        public int Duration { get; set; }
        public int LessonId { get; set; }
    }

我正在尝试构建可以被Angular使用的嵌套JSON,如下所示:

[{ Name: "Functions", 
   Lessons: [{ Name: "Intro to Functions",
           Activities: [ 
                 { Name: "Activity Quiz 1", Duration: 5, Date: "6/10/2014", Time: "18:55:00", Score: 80}, 
                 {Name: "Domain and Range", Duration: 36, Date: "6/10/2014", Time: "19:33:00", Score: 0}, 
                 {Name: "Activity Quiz 2", Duration: 4, Date: "6/10/2014", Time: "19:37:00", Score: 100}
                           ]
          }]
 }, 
{ Name: "Linear Functions", 
   Lessons: [{ Name: "Intro To Linear Functions",
           Activities: [ 
                 {Name: "Authentic Task: 1", Duration: 0, CompletedDate: "6/23/2014", CompletedTime: "13:54:00", Score: 0}, 
                 {Name: "Activity Quiz 3", Duration: 4, CompletedDate: "6/18/2014", CompletedTime: "14:12:00", Score: 80}, 
                 {Name: "Step Functions", Duration: 46, CompletedDate: "6/18/2014", CompletedTime: "14:59:00", Score: 0}
                           ]
          }]
 }
]

以下是我的尝试:

    var result = dt.AsEnumerable()
        .GroupBy(r => new { ID = r["Section"] })
        .Select(c => new Section
        {
            Name = c.Key.ID.ToString(),
            Lessons = c.Select(l => new Lesson
                {
                    Name = l["Lesson"].ToString(),
                    Activities = c.
                    .Select(a => new Activity
                    {
                        Name = a["Activity"].ToString(),
                        CompletedDate = a["Date"].ToString(),
                        CompletedTime = a["Time"].ToString(),
                        Score = Convert.ToInt32(a["Score"]),
                        Duration = Convert.ToInt32(a["Duration"])
                    }).ToList()
                }).ToList()
        }).ToList();

不幸的是,它没有返回正确的数据。这些部分看起来很好,但活动没有正确地链接到课程,而是链接到部分。所以我尝试利用Ids并将其分解成碎片:

var data = dt.AsEnumerable();

var sections = data
    .GroupBy(r => new { ID = r["SectionId"] }).Select(c => new Chapter
    {
        Id = Convert.ToInt32(c.Key.ID),
        Name = c.Select(n => n["Section"]).FirstOrDefault().ToString()
    }).Distinct().ToList();

var lessons = data
    .GroupBy(r => new { ID = r["LessonId"] }).Select(c => new Lesson
    {
        Id = Convert.ToInt32(c.Key.ID),
        Name = c.Select(n => n["Lesson"]).FirstOrDefault().ToString()
    }).Distinct().ToList();

var activities = data
    .Select(l => new Activity
    {
        Name = l["Activity"].ToString(),
        LessonId = Convert.ToInt32(l["LessonId"])
    }).ToList();

每个查询的数据看起来都是正确的,但最终我仍然无法获得我想要的数据。任何帮助或建议表示赞赏

编辑:

这是Angular数据绑定部分(studentData是范围上的嵌套对象):

            <table class="table">
                <thead>
                    <tr>
                        <th>Activities</th>
                        <th>Completed Date</th>
                        <th>Completed Time</th>
                        <th>Score</th>
                        <th>Status</th>
                        <th>Duration (hh:mm:ss)</th>
                    </tr>
                </thead>
                <tbody ng-repeat="section in studentData">
                    <tr>
                        <td><strong>{{section.Name}}</strong></td>
                        <td></td>
                        <td></td>
                        <td></td>
                        <td></td>
                        <td></td>
                    </tr>
                   <tr ng-repeat="lesson in section.Lessons">
                    <td>
                     <table>
                        <tr>
                          <td>&nbsp;&nbsp;&nbsp;&nbsp;{{lesson.Name}}</td>
                          <td></td>
                          <td></td>
                          <td></td>
                          <td></td>
                          <td></td>
                        </tr>
                        <tr ng-repeat="activity in lesson.Activities">
                          <td>{{activity.Name}}</td>
                          <td>{{activity.CompletedDate}}</td>
                          <td>{{activity.CompletedTime}}</td>
                          <td>{{activity.Score}}</td>
                          <td>{{activity.Score}}</td>
                          <td>{{activity.Duration}}</td>
                       </tr>
                     </table>
                   </td>
                 </tr>
               </tbody>
            </table>

2 个答案:

答案 0 :(得分:1)

这有帮助吗?

var grps= 
    dt.Rows.OfType<DataRow>()
        .GroupBy (r => r["SectionId"].ToString() + "|" + r["Section"].ToString() 
                      + "|" + r["LessonId"].ToString() + "|" + r["Lesson"].ToString()
                      + "|" + r["Activity"].ToString() + "|" + r["Date"].ToString()  + "|" + r["Time"].ToString() 
                 );

答案 1 :(得分:1)

我让事情变得复杂:

 var data = dt.AsEnumerable();

    var sections = data
        .GroupBy(r => new { ID = r["SectionId"] }).Select(c => new Chapter
        {
            Id = (int)c.Select(n => n["SectionId"]).FirstOrDefault(),
            Name = (string)c.Select(n => n["Section"]).FirstOrDefault(),
            Lessons = new List<Lesson>()
        }).Distinct().ToList();

    var lessons = data
        .GroupBy(r => new { ID = r["LessonId"] }).Select(l => new Lesson
        {
            Id = (int)l.Select(n => n["LessonId"]).FirstOrDefault(),
            Name = l.Select(n => n["Lesson"]).FirstOrDefault().ToString(),
            Activities = new List<Activity>(),
            ChapterId = (int)l.Select(n => n["SectionId"]).FirstOrDefault()
        }).Distinct().ToList();

    var activities = data
        .Select(a => new Activity
        {
            Name = (string)a["Activity"],
            Date = (string)a["Date"],
            Time = (string)a["Time"],
            Score = (int)a["Score"],
            Duration = (int)a["Duration"],
            LessonId = (int)a["Lessonid"]
        }).ToList();


    foreach (var lesson in lessons)
    {
        var activitiesToAdd = activities.Where(a => a.LessonId == lesson.Id);
        lesson.Activities.AddRange(activitiesToAdd);
    }

    foreach (var section in sections)
    {
        var lessonsToAdd = lessons.Where(l => l.SectionId == section.Id);
        section.Lessons.AddRange(lessonsToAdd);
    }

部分现在包含嵌套对象