Come unirti a due raccolte e trasporre una raccolta come entità usando LINQ (C#)
Domanda
Ho le seguenti lezioni:
public class Student
{
public string StudentID { get; set; }
public string StudentName { get; set; }
}
public class Marks
{
public string StudentID { get; set; }
public string SubjectName { get; set; }
public string Score { get; set; }
}
Popolare la collezione:
Collection<Student> objStudentCollection = new Collection<Student>();
Student student = new Student();
student.StudentID = "104517";
student.StudentName = "John";
objStudentCollection.Add(student);
student = new Student();
student.StudentID = "104520";
student.StudentName = "Stella";
objStudentCollection.Add(student);
Collection<Marks> objMarkCollection = new Collection<Marks>();
Marks marks = new Marks();
marks.StudentID = "104517";
marks.SubjectName = "English";
marks.Score = "85";
objMarkCollection.Add(marks);
marks = new Marks();
marks.StudentID = "104517";
marks.SubjectName = "Science";
marks.Score = "60";
objMarkCollection.Add(marks);
marks = new Marks();
marks.StudentID = "104517";
marks.SubjectName = "Mathematics";
marks.Score = "75";
objMarkCollection.Add(marks);
marks = new Marks();
marks.StudentID = "104517";
marks.SubjectName = "Optional 1";
marks.Score = "75";
objMarkCollection.Add(marks);
marks = new Marks();
marks.StudentID = "104520";
marks.SubjectName = "French";
marks.Score = "54";
objMarkCollection.Add(marks);
marks = new Marks();
marks.StudentID = "104520";
marks.SubjectName = "Science";
marks.Score = "60";
objMarkCollection.Add(marks);
marks = new Marks();
marks.StudentID = "104520";
marks.SubjectName = "Mathematics";
marks.Score = "75";
objMarkCollection.Add(marks);
marks = new Marks();
marks.StudentID = "104520";
marks.SubjectName = "Optional 1";
marks.Score = "50";
objMarkCollection.Add(marks);
Vorrei legare le raccolte di cui sopra in GridView per visualizzare come:
StudentId | StudentName | Inglese | Francese | Matematica | Scienza | Opzionale 1 | Totale
Soluzione
Penso che tu abbia bisogno di utilizzare il GroupJoin Metodo per ottenere quello che stai cercando. Potresti farlo in questo modo se l'elenco degli argomenti se fissati e non cambierà:
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)),
})
Non è il codice più bello del mondo, ma ti darà un tipo anonimo con ogni riga contenente i dati che hai chiesto. Potresti sostituire Sum
insieme a SingleOrDefault
Se c'è sempre un solo segno per argomento.
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();
Questa seconda soluzione ti creerà un tipo anonimo con ogni studente e una raccolta di marchi tra cui ogni argomento (quelli che lo studente non ha preso avrà un punteggio 0).