我有一个复杂的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
};
所以基本上我试图在孙子上加上总和 值。我已经在评论中添加了我想要返回的值 进入ViewModel,但我无法弄清楚如何计算 答案。答案应该在组中还是在分组后必须在另一个查询中?如果是这样,我如何在组后使用变量z。
我得到了错误的类别列表,因为我只是得到了 有问题的类别得到解答。但我知道我可以使用from / into / isdefault,所以请不要担心。
答案 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;