Projection helps us developer to retrieve desired result from the collection . LINQ provides two projection operator. Select and SelectMany. Select works with one collection whereas SelectMany works with more than one collection.
Projection transforms the query result into the form defined by the developer. There are two projection operators in LINQ

Let us say, there is a class
class Student
{
public string Name { get; set; }
public string RollNumber { get; set; }
public List Subject { get; set; }
}
And a function returning List<Student> as below,
static List GetStudents()
{
List students = new List{
new Student {
Name = "Dhananjay",
RollNumber = "1",
Subject = new new List{"Math","Phy"}},
new Student {
Name = "Scott",
RollNumber = "2",
Subject = new new List{"Che","Phy"}},
new Student {
Name = "John",
RollNumber = "3",
Subject = new new List{"Hindi","Phy"}}};
return students;
}
Select operator
Below query will return name and roll number of all the students.
// Reteriving the result in Anonymous class
var result2 = from r in GetStudents()
select new { r.RollNumber , r.Name };
foreach (var r in result2)
{
Console.WriteLine(r);
}
Output

Below query will project name of the student’s starts with D.
var results = from r in GetStudents()
where r.Name.StartsWith("D")
Select r;
foreach (var r in results)
{
Console.WriteLine(r.Name);
}
Output

Above was very simple query let us modify the display function and try to display subject of the student
foreach (var r in results)
{
Console.WriteLine(r.Subject);
}
Output

If you notice the above output, we are not getting the proper output and it is saying that Subject is generic list. So to fetch we need to enumerate through the list.
Now question is how to retrieve all the subjects of students?
SelectMany
So to retrieve query from more than one collection SelectMany come into action.
var result3 = from r in GetStudents()
select r;
foreach (var r in
result3.SelectMany(Student => Student.Subject))
{
Console.Writeline(r);
}
Above query will return the entire subjects of all the students.

The other way to apply SelectMany operator is directly apply on the retrieval query as below,
var result = GetStudents().AsQueryable().SelectMany(Subject => Subject.Subject);
foreach (var r in result)
{
Console.WriteLine(r);
}
Output

Full Source code is as below,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication9
{
classProgram
{
staticvoid Main(string[] args)
{
// Reteriving all students with name D
var result1 = from r in GetStudents()
where r.Name.StartsWith("D")
select r;
foreach (var r in result1)
{
Console.WriteLine(r.Name);
}
// Reteriving the result in Anonymous class
var result2 = from r in GetStudents()
selectnew { r.RollNumber, r.Name };
foreach (var r in result2)
{
Console.WriteLine(r);
}
// Reteriving using SelectMany
var result3 = from r in GetStudents()
select r;
foreach (var r in result3.SelectMany(Student => Student.Subject))
{
Console.WriteLine(r);
}
// directly applying SelectMany
var result = GetStudents().AsQueryable().SelectMany(Subject => Subject.Subject);
foreach (var r in result)
{
Console.WriteLine(r);
}
Console.Read();
}
static List GetStudents()
{
List students = new List{
new Student {
Name = "Dhananjay",
RollNumber = "1",
Subject = new new List{"Math","Phy"}},
new Student {
Name = "Scott",
RollNumber = "2",
Subject = new new List{"Che","Phy"}},
new Student {
Name = "John",
RollNumber = "3",
Subject = new new List{"Hindi","Phy"}}};
return students;
}
}
classStudent
{
publicstring Name { get; set; }
publicstring RollNumber { get; set; }
publicList Subject { get; set; }
}
}
I hope this article was useful. Thanks for reading. Happy Coding