问题
I have a list of Questions that is grouped by Subject and Parent.
For example I would have
Subject 1
Parent 1
Question 1
Subject2
Parent2
Question2
Subject1
Parent2
Question3
Subject2
Parent2
Question4
Now I wish to display some sort of tree view, ie something like
Subject 1
Parent 1
Question 1
Parent 2
Question 2
Question 3
Subject 2
Parent 1
Question 4
Parent 2
Question 5
Question 6
How can I achieve that with GroupBy LINQ statement?
I have tried something which is not working yet
var questionSubjectGrps = questionsBll.GetReportQuestions()
.Where(x => x.VersionId == iLatestVersion)
.OrderByDescending(x => x.SubjectId)
.GroupBy(subject => new { subject.ReportQuestionTitle, subject.ParentId });
Any help will be very much appreciated
Thanks
**********************NEW CODE****************
IEnumerable<ReportQuestion> questionSubjectGrps = questionsBll.GetReportQuestions().Where(x => x.VersionId == iLatestVersion);
var tree = questionSubjectGrps.Select(questSubGrps => questSubGrps.SubjectId)
.Distinct()
.Select(q => new
{
Subject = q.SubjectId,
Parents = questionSubjectGrps
.Where(q2 => q2.SubjectId == q.SubjectId)
.Select(q2 => new
{
Parent = q2.ParentId,
Question = questionSubjectGrps
.Where(q3 => q3.SubjectId == q.SubjectId && q3.ParentId == q2.ParentId)
.Select(q3 => q3.QuestionId)
})
});
回答1:
You can do this with a couple of levels of GroupBy
as follows.
This input matches the expected output you gave, rather than the input you gave.
var questions = new List<Question>
{
new Question { SubjectId = 1, ParentId = 1, QuestionId = 1 },
new Question { SubjectId = 1, ParentId = 2, QuestionId = 3 },
new Question { SubjectId = 2, ParentId = 2, QuestionId = 2 },
new Question { SubjectId = 2, ParentId = 2, QuestionId = 3 },
new Question { SubjectId = 2, ParentId = 1, QuestionId = 4 },
new Question { SubjectId = 2, ParentId = 2, QuestionId = 5 },
new Question { SubjectId = 2, ParentId = 2, QuestionId = 6 },
};
The first GroupBy
groups by the subject ID. The second GroupBy
groups each subject group by parent ID.
var grouped = questions.GroupBy(
q => q.SubjectId,
(sid, qs) => new { SubjectId = sid, Groups = qs.GroupBy(q => q.ParentId) });
With two levels of GroupBy
you need three foreach
loops to get all the questions.
foreach (var subjectGroup in grouped)
{
Console.WriteLine("Subject {0}", subjectGroup.SubjectId);
foreach (var parentGroup in subjectGroup.Groups)
{
Console.WriteLine("\tParent {0}", parentGroup.Key);
foreach (var question in parentGroup)
{
Console.WriteLine("\t\tQuestion {0}", question.QuestionId);
}
}
}
回答2:
I don't think a GroupBy is actually what you want - I think you want a hierarchical structure. e.g:
var questionSubjectGrps = questionsBll
.GetReportQuestions()
.Tolist();
var tree = questionSubjectGrps.Select(questionSubjectGrps => q.SubjectId)
.Distinct()
.Select(q => new
{
Subject = q.SubjectId,
Parents = questionSubjectGrps
.Where(q2 => q2.SubjectId == q.SubjectId)
.Select(q2 => new
{
Parent = q2.ParentId,
Question = questionSubjectGrps
.Where(q3 => q3.SubjectId == q.SubjectId && q3.ParentId == q2.ParentId)
.Select(q3 => q3.QuestionId)
})
});
来源:https://stackoverflow.com/questions/16735841/groupby-linq-statement