【问题标题】:Complex grouping by grandchildren按孙子复杂分组
【发布时间】:2014-08-01 04:49:36
【问题描述】:

我有一个复杂的 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. 所以本质上我正在尝试对孙子的总和进行分组 价值观。我已将我要返回的值放入 cmets 进入 ViewModel,但我不知道如何计算 答案。答案应该在组中还是必须在分组后的另一个查询中?如果是这样,我如何在组后使用变量z。

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

【问题讨论】:

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


    【解决方案1】:

    我已经想通了(这样做我的大脑几乎要爆炸了)。 我花了一段时间才弄清楚,由于我在组中没有任何问题或答案(否则他们不会只按类别分组),我必须将整个类别对象传递给 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);
    

    这个答案有效,但是有没有优化这个代码?

    【讨论】:

    • 尝试使用.Count(x =&gt; bla) 而不是.Where(x =&gt; bla).Count()
    • 如何在 linq 查询中做到这一点?
    • 类似这样的:Evaluation2 = newGroup.Key.x.Questions.SelectMany(a =&gt; a.Answers).Count(b =&gt; b.yourEvaluation == 2 &amp;&amp; b.entityId == this.LoggedInEntity.EntityId)?
    • 谢谢,我试试
    【解决方案2】:

    这是上述答案的优化版

    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;
    

    【讨论】:

      猜你喜欢
      • 2021-03-29
      • 1970-01-01
      • 2014-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多