Suppose I have the following classes
public class Student
{
public int Id {get; set;}
public int ClassId {get; set;}
public string ClassName {get; set;}
public string Name {get; set;}
public int Age {get; set;}
}
public class StudentDTO
{
public string Name {get; set;}
public int Age {get; set;}
}
public class ClassStudent
{
public string ClassName {get; set;}
public List<StudentDTO> StudentDTOs {get; set;}
}
and I have a var listOfStudents = new List<Student>()
;
Now I enetered values into listOfStudents and grouped the according to ClassId as follows:
listOfStudents = listOfStudents.GroupedBy(l => l.ClassId).ToList();
I want the output to be a list of type ClassStudent
that each group of listOfStudents
is an element of this list
I am implementing it as follows:
listOfStudents.Foreach(s =>
{
var classStudents = listOfStudents.Where(ls => ls.ClassId == s.Key).ToList();
classes.Add(new ClassStudents
{
ClassName = classStudents.FirstOrDefault().ClassName,
StudentDTOs = classStudents.Select(ls => new StudentDTO
{
Name = ls.Name,
Age = ls.Age
}).ToList()
});
});
As you notice in my approach, Grouping Element is no longer of any effect, because I still had to resort to a foreach and where elements to fill the classes.
So I can simple do as follows instead
var classIds = listOfStudents.Select(l => l.ClassId).Distinct().ToList();
foreach(int id in classIds)
{...}
Basically, grouping is meaningless here
Is their a way to avoid the foreach and access the elements directly inside the groups?
Ideally something like this:
classes = listOfStudents.Select(g => new ClassStudent
{
ClassName = g.Elements.FirstOrDefault().ClassName,
StudentDTOs = g.Elements.Select(ls => new StudentDTO
{
Name = ls.Name,
Age = ls.Age
}).ToList()
});
CodePudding user response:
Better to add ClassName
to grouping key. Leaving ClassId
in grouping key if ClassName
is not unique:
var classes = listOfStudents
.GroupBy(s => new { s.ClassId, s.ClassName})
.Select(g => new ClassStudents
{
ClassName = g.Key.ClassName,
StudentDTOs = g.Select(ls => new StudentDTO
{
Name = ls.Name,
Age = ls.Age
}).ToList()
})
.ToList();