基于展平记录集的嵌套组

时间:2015-10-10 22:44:10

标签: c# sql entity-framework linq group-by

我有来自API的以下回复。如何将它们分组到以下结构中? enter image description here

Student[]
   - Name
   - Classes[]
      - ClassName
      - ClassId
      - ClassCategories[]
          - CategoryName
          - CategoryWeight
          - Assignments[]
             - AssignmentName
             - Score

我设法将它们分组到“类”级别但无法获得每个类的ClassCategories

 var data = (from result in results
                        group result by new { result.StudentId, result.FirstName, result.LastName, result.MiddleInitial }
                        into StudentGroup
                        select new GroupedStudent
                        {
                            StudentId = StudentGroup.Key.StudentId,
                            FullName = string.Format("{0} {1} {2}", StudentGroup.Key.FirstName, StudentGroup.Key.MiddleInitial, StudentGroup.Key.LastName).Replace("  ", " "),
                            Classes = from result in results
                                   group result by new { result.ClassId, result.ClassName } into ClassGroup
                                   select new groupedClass
                                   {
                                       ClassName = ClassGroup.Key.ClassName,
                                       ClassId = ClassGroup.Key.ClassId,
                                       ClassCategories = ...
                                   })
                        }).ToList();

有人可以帮助我吗?谢谢。

2 个答案:

答案 0 :(得分:1)

首先,您从StudentGroup创建ClassGroup而不是结果。

Classes = from s in StudentGroup group result by new { s.ClassId, s.ClassName } into ClassGroup

完整的linq查询如下:

    var data =
        (from result in results
         group result by new { result.StudentId, result.FirstName, result.LastName, result.MiddleInitial } into StudentGroup
         select new
         {
             StudentId = StudentGroup.Key.StudentId,
             FullName = string.Format("{0} {1} {2}", StudentGroup.Key.FirstName, StudentGroup.Key.MiddleInitial, StudentGroup.Key.LastName).Replace("  ", " "),
             Classes = (from s in StudentGroup
                        group s by new { s.ClassId, s.ClassName } into ClassGroup
                        select new
                        {
                            ClassId = ClassGroup.Key.ClassId,
                            ClassName = ClassGroup.Key.ClassName,
                            ClassCategories = (from c in ClassGroup
                                               group c by new { c.CategoryName, c.CategoryWeight } into CategoryGroup
                                               select new
                                               {
                                                   CategoryName = CategoryGroup.Key.CategoryName,
                                                   CategoryWeight = CategoryGroup.Key.CategoryWeight,
                                                   Assignments = (from ct in CategoryGroup
                                                                  group ct by new { ct.AssignmentName, ct.Score } into AssingnmentGroup
                                                                  select new
                                                                  {
                                                                      AssignmentName = AssingnmentGroup.Key.AssignmentName,
                                                                      Score = AssingnmentGroup.Key.Score
                                                                  }).ToList()
                                               }).ToList()
                        }).ToList()
         }).ToList();

例如,如果您想要访问第一个Assignment的分数,您可以这样:

var student = data.FirstOrDefault();
var score = student.Classes[0].ClassCategories[0].Assignments[0].Score;

答案 1 :(得分:0)

这通常就是我的做法。

  • 创建一个用于存储数据的类
  • 创建该类类型的列表
  • 在您的案例中,您可以使用子类
  • 代替string dataRow

// get data from webservice
var json = webClient.DownloadString(url);
var values = JsonConvert.DeserializeObject<JArray>(json);

// create a list to save all the element
List<myClass> classList = new List<myClass>();

// process every row
foreach (string dataRow in values)
{
  string[] dataField = dataRow.Split(',');

  // have a constructor to assign each value to this element
  myClass ctROW = new myClass(dataField);
  classList.add(ctROW );