由孙子组成的复杂分组

时间:2014-06-11 08:05:18

标签: c# linq group-by linq-to-entities entity-framework-6

我有一个复杂的LINQ查询,我正在努力弄清楚。 我有这样的域模型:

ReviewCategory > has ReviewQuestions > has ReviewAnswers

我要做的是计算某个类别中所有问题的某个值的答案数。我正在使用一个非常古老的经典asp系统构建,它使用多个数据库存储过程来完成这项工作,但我认为它可以通过LINQ to EF进行管理。

我有一个ViewModel,我正在设置每个答案值的类别名称,顺序和计数,因此视图模型将包含一个类别列表和响应数量的计算。

这是我坚持的代码:

pcvm.Categories = from x in _repository.GetAll<ReviewCategory>()
                  where x.include == true &&
                       ((x.AuditQuestionGroupId != null ? x.AuditQuestionGroupId : 0) == this.LoggedInEntity.AuditQuestionGroupId)
                  from y in x.Questions
                  where y.include == true
                  from z in y.Answers
                  where z.entityId == this.LoggedInEntity.EntityId
                  orderby x.order != null ? 999 : x.order, x.name
                  group x by new { x.id, x.name, x.order, z.yourEvaluation, z.yourResponse } into newGroup
                  select new PracticeConductCategoriesViewModel
                  {
                      Id = newGroup.Key.id, // The categoryId
                      Name = newGroup.Key.name, // The category name
                      Order = newGroup.Key.order, // The category order
                      EvaluationNR = newGroup.Key.yourEvaluation, // The number of answers where yourEvaluation = 0
                      Evaluation1 = newGroup.Key.yourEvaluation, // The number of answers where yourEvaluation = 1 etc etc.
                      Evaluation2 = newGroup.Key.yourEvaluation,
                      Evaluation3 = newGroup.Key.yourEvaluation,
                      Evaluation4 =  newGroup.Key.yourEvaluation,
                      Percentage = newGroup.Key.yourEvaluation // Percentage of yourEvaluations answered for each category
                   };
  1. 所以基本上我试图在孙子上加上总和 值。我已经在评论中添加了我想要返回的值 进入ViewModel,但我无法弄清楚如何计算 答案。答案应该在组中还是在分组后必须在另一个查询中?如果是这样,我如何在组后使用变量z。

  2. 我得到了错误的类别列表,因为我只是得到了     有问题的类别得到解答。但我知道我可以使用from / into / isdefault,所以请不要担心。

2 个答案:

答案 0 :(得分:0)

我已经想到了这一点(我的大脑几乎爆炸了)。 我花了一段时间才弄明白,因为我在组中没有任何问题或答案(否则他们不会按类别分组),我必须将整个类别对象传递给select new,然后访问孙子(通过另一个子查询的答案) 那样。

以下是工作代码:


PracticeConductViewModel pcvm = new PracticeConductViewModel();
            pcvm.Categories = (from x in _repository.GetAll<ReviewCategory>()
                               where x.include == true &&
                               ((x.AuditQuestionGroupId != null ? x.AuditQuestionGroupId : 0) == this.LoggedInEntity.AuditQuestionGroupId)
                               from y in x.Questions
                               where y.include == true                               
                               group x by new { x, x.id, x.name, x.order } into newGroup
                               orderby newGroup.Key.order != null ? 999 : newGroup.Key.order, newGroup.Key.name
                               select new PracticeConductCategoriesViewModel
                               {
                                   Id = newGroup.Key.id, // The categoryId
                                   name = newGroup.Key.name, // The category name
                                   order = newGroup.Key.order, // The order
                                   Evaluation1 = (from a in newGroup.Key.x.Questions
                                                  from b in a.Answers
                                                  where b.yourEvaluation == 1 && b.entityId == this.LoggedInEntity.EntityId
                                                  select a).Count(),
                                   Evaluation2 = (from a in newGroup.Key.x.Questions
                                                  from b in a.Answers
                                                  where b.yourEvaluation == 2 && b.entityId == this.LoggedInEntity.EntityId
                                                  select a).Count(),
                                   Evaluation3 = (from a in newGroup.Key.x.Questions
                                                  from b in a.Answers
                                                  where b.yourEvaluation == 3 && b.entityId == this.LoggedInEntity.EntityId
                                                  select a).Count(),
                                   Evaluation4 = (from a in newGroup.Key.x.Questions
                                                  from b in a.Answers
                                                  where b.yourEvaluation == 4 && b.entityId == this.LoggedInEntity.EntityId
                                                  select a).Count(),
                                   EvaluationNR = (from a in newGroup.Key.x.Questions
                                                  from b in a.Answers
                                                  where b.yourEvaluation == 0 && b.entityId == this.LoggedInEntity.EntityId
                                                  select a).Count(),
                                   Response1 = (from a in newGroup.Key.x.Questions
                                                  from b in a.Answers
                                                  where b.yourResponse == 1 && b.entityId == this.LoggedInEntity.EntityId
                                                  select a).Count(),
                                   Response2 = (from a in newGroup.Key.x.Questions
                                                  from b in a.Answers
                                                  where b.yourResponse == 2 && b.entityId == this.LoggedInEntity.EntityId
                                                  select a).Count(),
                                   Response3 = (from a in newGroup.Key.x.Questions
                                                from b in a.Answers
                                                where b.yourResponse == 3 && b.entityId == this.LoggedInEntity.EntityId
                                                select a).Count(),
                                   //Percentage = newGroup.Key.yourEvaluation // Percentage of yourEvaluations answered for each question
                               })
                               .ToList();


            return View(pcvm);

这个答案有效,但无论如何都要优化这段代码吗?

答案 1 :(得分:0)

这是上述答案的优化版

var categories = (from x in _repository.GetAll<ReviewCategory>()
                              from y in x.Questions
                              where y.include == true && x.include == true &&
                                  ((x.AuditQuestionGroupId != null ? x.AuditQuestionGroupId : 0) == this.LoggedInEntity.AuditQuestionGroupId)
                              group x by new { category = x } into newGroup
                              select new ConductCategoriesViewModel
                              {
                                  Id = newGroup.Key.category.id,
                                  name = newGroup.Key.category.name,
                                  order = newGroup.Key.category.order != null ? newGroup.Key.category.order : 999,
                                  Evaluation1 = newGroup.Key.category.Questions.SelectMany(a => a.Answers)
                                                .Count(b => b.Question.radioDisplay == true && b.Question.include == true && b.yourEvaluation == 1 && b.entityId == this.LoggedInEntity.EntityId && b.entityLevelAudit == true),
                                  Evaluation2 = newGroup.Key.category.Questions.SelectMany(a => a.Answers)
                                                .Count(b => b.Question.radioDisplay == true && b.Question.include == true && b.yourEvaluation == 2 && b.entityId == this.LoggedInEntity.EntityId && b.entityLevelAudit == true),
                                  Evaluation3 = newGroup.Key.category.Questions.SelectMany(a => a.Answers)
                                                .Count(b => b.Question.radioDisplay == true && b.Question.include == true && b.yourEvaluation == 3 && b.entityId == this.LoggedInEntity.EntityId && b.entityLevelAudit == true),
                                  Evaluation4 = newGroup.Key.category.Questions.SelectMany(a => a.Answers)
                                                .Count(b => b.Question.radioDisplay == true && b.Question.include == true && b.yourEvaluation == 4 && b.entityId == this.LoggedInEntity.EntityId && b.entityLevelAudit == true),
                                  EvaluationNR = newGroup.Key.category.Questions.SelectMany(a => a.Answers)
                                                .Count(b => b.Question.radioDisplay == true && b.Question.include == true && b.yourEvaluation == 0 && b.entityId == this.LoggedInEntity.EntityId && b.entityLevelAudit == true),
                                  Response1 = newGroup.Key.category.Questions.SelectMany(a => a.Answers)
                                                .Count(b => b.Question.radioDisplay == true && b.Question.include == true && b.yourResponse == 1 && b.entityId == this.LoggedInEntity.EntityId && b.entityLevelAudit == true),
                                  Response2 = newGroup.Key.category.Questions.SelectMany(a => a.Answers)
                                                .Count(b => b.Question.radioDisplay == true && b.Question.include == true && b.yourResponse == 2 && b.entityId == this.LoggedInEntity.EntityId && b.entityLevelAudit == true),
                                  Response3 = newGroup.Key.category.Questions.SelectMany(a => a.Answers)
                                                .Count(b => b.Question.radioDisplay == true && b.Question.include == true && b.yourResponse == 3 && b.entityId == this.LoggedInEntity.EntityId && b.entityLevelAudit == true),
                                  QuestionsAnswered = newGroup.Key.category.Questions.SelectMany(x => x.Answers)
                                                .Count(b => b.yourEvaluation != null && b.entityId == this.LoggedInEntity.EntityId && b.entityLevelAudit == true && b.Question.include == true && b.Question.radioDisplay == true),
                                  TotalQuestions = newGroup.Key.category.Questions.Count(x => x.include == true && x.radioDisplay == true) == 0 ? 0 : newGroup.Key.category.Questions.Count(x => x.include == true && x.radioDisplay == true)
                              })
                                .OrderBy(x => x.order != null ? x.order : 999).ThenBy(x => x.name) // It doesn't sort properly if this is in the linq query for some reason.
                               .ToList();
            return categories;