【问题标题】:Nested group by based on flatten record set基于展平记录集的嵌套分组依据
【发布时间】:2016-01-08 16:04:06
【问题描述】:

我收到了来自 API 的以下响应。如何将它们分组到以下结构中?

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();

谁能帮帮我?谢谢。

【问题讨论】:

  • “结果”的类型是什么?
  • @jhmt:结果以通用列表形式返回
  • 有人知道这是否可能吗?
  • 好的,那么结果中的一个实例具有以下属性:ClassId、ClassName、StudentName、Grade、GradePercent、AssignmentName、Grading、Points、Score、Percent、CategoryName 和 CategoryWeight,不是吗?
  • @jhmt 是的,但是我想加入学生的“结果”,然后每个学生都有他的注册班级,每个班级都有自己的班级类别,每个类别都有自己的作业.这可能吗?

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


【解决方案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();

例如,如果要访问第一个作业的分数,可以这样获取:

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

【讨论】:

  • 感谢您的帮助,我已经整理好了。谢谢!
【解决方案2】:

这通常是我的做法。

  • 创建一个类来存储您的数据
  • 创建该类类型的列表
  • 在你的情况下,而不是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 );

【讨论】:

  • 嗨,感谢您的回复,不确定这是否是一个好习惯,因为我的结果集中可能有很多重复的 ClassId。
  • 我在说我是怎么做的。我没有得到重复的数据。当然,这只是一个普遍的想法。但是在完成JsonConvert.DeserializeObject&lt;JArray&gt;(json); 之后,您应该非常清楚下一步该做什么。
  • 如果这对您不起作用,请告诉我,我将删除我的答案。不知道为什么有人在不发表评论的情况下投了反对票。
  • Calos Oropeze 我试过了,这是可行的,但我更喜欢使用 linq 来完成它。再次感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-15
  • 2019-04-29
  • 2019-03-05
  • 1970-01-01
  • 2020-10-04
相关资源
最近更新 更多