Я думаю, вам нужно использовать метод GroupJoin , чтобы получить то, что вам нужно.
Вы можете сделать это следующим образом, если список предметов фиксирован и не будет меняться:
var q =
objStudentCollection
.GroupJoin(
objMarkCollection,
stu => stu.StudentID,
mark => mark.StudentID,
(stu, mark) =>
new
{
student.StudentID,
student.StudentName,
English = mark.Where(m => m.SubjectName == "English").Sum(m => Convert.ToInt32(m.Score)),
French = mark.Where(m => m.SubjectName == "French").Sum(m => Convert.ToInt32(m.Score)),
Mathematics = mark.Where(m => m.SubjectName == "Mathematics").Sum(m => Convert.ToInt32(m.Score)),
Science = mark.Where(m => m.SubjectName == "Science").Sum(m => Convert.ToInt32(m.Score)),
Optional1 = mark.Where(m => m.SubjectName == "Optional 1").Sum(m => Convert.ToInt32(m.Score)),
Total = mark.Sum(m => Convert.ToInt32(m.Score)),
})
Это не самый красивый код в мире, но он даст вам анонимный тип с каждой строкой, содержащей запрашиваемые вами данные. Вы можете заменить Sum
на SingleOrDefault
, если на каждый предмет имеется только одна отметка.
var subjects =
objMarkCollection
.Select(mark => mark.SubjectName)
.Distinct()
.Dump();
var q =
objStudentCollection
.GroupJoin(
objMarkCollection,
stu => stu.StudentID,
mark => mark.StudentID,
(stu, mark) =>
new
{
student.StudentID,
student.StudentName,
Marks =
from s in subjects
join m in mark on s equals m.SubjectName into outer
from o in outer.DefaultIfEmpty()
select new
{
SubjectName = s,
Score = (o == null) ? 0 : Convert.ToInt32(o.Score),
},
Total = mark.Sum(m => Convert.ToInt32(m.Score)),
})
.Dump();
Это второе решение создаст вам анонимный тип для каждого учащегося и набор оценок, включающий каждый предмет (те, которые студент не сдал, получат 0 баллов).