Projection Operators
A projector machine projects slides or film onto a screen, which means a projector transforms one form of thing into another. Similarly, in LINQ, projection means taking all or some properties of an object, either modifying them or not modifying them, and projecting them into a new type, which could be the same or anonymous.
Follow the following examples for better understanding:
Example 1. Projecting object properties into different objects
public class Employee
{
public int Id { get; set;}
public string Name { get; set;}
public int Phone { get; set;}
public string Gender {get;set;}
public string MaritalStatus {get;set;}
}
public class Contact
{
public int ContactId { get; set;}
public string PersonName { get; set;}
public int Phone { get; set;}
}
List<Employee> emps=new List<Employee> ()
{
new Employee() {Id=1,Name="Sachin",Phone=345678901,Gender="Male", MaritalStatus ="UnMarried"},
new Employee(){Id=1,Name="Nivi",Phone=345678901, Gender="Female", MaritalStatus ="UnMarried"}
}
var contacts= emps.Select(x=> new Contact
{
ContactId=x.Id,
Phone=x.Phone,
PersonName=x.Name,
}).ToList();
In the above example, we are projecting Employee's properties to the Contact object, which has just three properties, i.e., ContactId, Phone, and PersonName
Example 2. Projecting object properties into an anonymous object
public class Employee
{
public int Id { get; set;}
public string Name { get; set;}
public int Phone { get; set;}
}
List<Employee> emps=new List<Employee> ()
{
new Employee() {Id=1,Name="Sachin",Phone=345678901},
new Employee(){Id=1,Name="Sachin",Phone=345678901}
}
var res= emps.Select(x=> new
{
Id=x.Id,
PhoneNumber=x.Phone,
Person=x.Name,
}).ToList();
In the above example, we are projecting properties of the Employee object to an unnamed (anonymous) object. The anonymous object have three properties, i.e., Id, PhoneNumber, and Person.
Example 3. Projecting object properties into the same object
public class Employee
{
public int Id { get; set;}
public string Name { get; set;}
public int Phone { get; set;}
}
List<Employee> emps=new List<Employee> ()
{
new Employee() {Id=1,Name="Sachin",Phone=345678901},
new Employee(){Id=1,Name="Sachin",Phone=345678901}
}
var employees= emps.Select(x=> new Employee
{
Id=x.Id,
PhoneNumber=x.Phone,
Person=x.Name,
}).ToList();
Example 4. Projecting object properties into a new object with modification
public class Employee
{
public int Id { get; set;}
public string Name { get; set;}
public int Phone { get; set;}
public string Gender {get;set;}
public string MaritalStatus {get;set;}
}
public class Contact
{
public int ContactId { get; set;}
public string PersonName { get; set;}
public int Phone { get; set;}
}
List<Employee> emps=new List<Employee> ()
{
new Employee() {Id=1,Name="Sachin",Phone=345678901,Gender="Male", MaritalStatus ="UnMarried"},
new Employee(){Id=1,Name="Nivi",Phone=345678901, Gender="Female", MaritalStatus ="UnMarried"}
}
var contacts = emps.Select(x => new Contact
{
ContactId = x.Id,
Phone = x.Phone,
PersonName =(x.Gender == "Female" && x.MaritalStatus == "Married") ? "Mrs." + x.Name :
(x.Gender == "Female" && x.MaritalStatus == "UnMarried") ?"Ms." + x.Name: "Mr"+x.Name,
}).ToList();
Notice that in the above example, we are computing the PersonName property of the Contact class object based on the MartialStatus and the Gender properties of the Employee object. I have used the nested ternary operator to achieve the following requirements:
- Gender="Female" and "MaritalStatus"= "Married" then Add "Mrs." prefix.
- Gender="Female" and "MaritalStatus" = UnMarried then Add "Ms." prefix else
- Add "Mr." prefix to the name property's value.
Types of LINQ Projection Operators
LINQ provides us with two flavors of projection operators, and each one has its own purpose:
- Select and
- Select many
In the upcoming chapters, we will learn all of these Projection Operators in detail with examples.
SelectMany Operator
we have already discussed in previous articles that like a projector machine projects slides or film on to a screen, means a projector transforms one form of things into other similarly In LINQ, projection means to take all or some properties of an object, either modify them or don't modify them and project them into a new type, same type or an anonymous type.
SelectMany Operator also belongs to the Projection Operators category which is used to project each element of a sequence to an IEnumerable<T> and flattens the resulting sequences into one sequence. Here the type (T) literally can be anything like collection of string, collection of char, collection of complex object anything like that
Let us understand this with an example. Consider the following Author class. Books property in this class is a collection of strings.
public class Author
{
public string Name { get; set; }
public string Gender { get; set; }
public List<string> Books { get; set; }
public static List<Author> GetAllAuthors()
{
List<Author> authorList = new List<Author >
{
new Author
{
Name = "Sachin",
Gender = "Male",
Books = new List<string> { "Book1 ", "Book2" }
},
new Author
{
Name = "Arjun",
Gender = "Male",
Books = new List<string> { "Book3 ", "Book4" }
},
new Author
{
Name = "Vikash",
Gender = "Male",
Books = new List<string> { "Book4 ", "Book5" }
},
new Author
{
Name = "Nivi",
Gender = "Female",
Books = new List<string> { "Book6 ", "Book7" }
},
};
return authorList;
}
}
Example 1 : Fetch all books written by a specific Author.
Here, if we use Select operator then we will get a hierarchal result which means to print the result we will have to use two foreach blocks.
public static void Main()
{
Author author =new Author();
var BooksByVikash = author.GetAllAuthors().Where(a => a.Name == "Vikash").Select(x=>x.Books);
foreach (var books in BooksByVikash)
{
foreach(var book in books)
{
Console.WriteLine(book);
}
}
Console.ReadLine();
}
As you can see there is something weird in here, this is because we are selecting a collection from a collection means GetAllAuthors itself returns a collection of Authors , now you must be thinking we only want the books written by a particular Author then why we did not use Single() to just fetch one particular author , actually we can't do so because Select is an extension method on IEnumerable<T> which means we can use select operator with a collection of things only and not with a singleton result.
In short if there is a collection property and we are selecting that property from a collection of object then we will end up with an IEnumerable<List<T>> which is a collection of collection.
To solve the above problem we have SelectMany projection operator which enables us to project each element of a sequence to an IEnumerable<T> and flattens the resulting sequences into one sequence.
The above example can be rewritten with SelectMany operator as shown below.
public static void Main()
{
Author author =new Author();
var BooksByVikash = author.GetAllAuthors().Where(a => a.Name == "Vikash").SelectMany(x=>x.Books);
foreach (var book in BooksByVikash)
{
Console.WriteLine(book);
}
Console.ReadLine();
}
Notice the results are now flattened, and to print the result we just used one foreach block instead of two.
Example 2: Rewrite Example1 using SQL like syntax.
When using SQL like syntax style, we don't use SelectMany, instead we will have an additional from clause, which will get its data from the results of the first from clause.
Authors author= new Author();
IEnumerable<string> booksByVikash= from Author in author. GetAllAuthors ()
from Book in Author.Books
select Book;
foreach (string Book in booksByVikash)
{
Console.WriteLine(Book);
}
Output:
SelectMany Operator
we have already discussed in previous articles that like a projector machine projects slides or film on to a screen, means a projector transforms one form of things into other similarly In LINQ, projection means to take all or some properties of an object, either modify them or don't modify them and project them into a new type, same type or an anonymous type.
SelectMany Operator also belongs to the Projection Operators category which is used to project each element of a sequence to an IEnumerable<T> and flattens the resulting sequences into one sequence. Here the type (T) literally can be anything like collection of string, collection of char, collection of complex object anything like that
Let us understand this with an example. Consider the following Author class. Books property in this class is a collection of strings.
public class Author
{
public string Name { get; set; }
public string Gender { get; set; }
public List<string> Books { get; set; }
public static List<Author> GetAllAuthors()
{
List<Author> authorList = new List<Author >
{
new Author
{
Name = "Sachin",
Gender = "Male",
Books = new List<string> { "Book1 ", "Book2" }
},
new Author
{
Name = "Arjun",
Gender = "Male",
Books = new List<string> { "Book3 ", "Book4" }
},
new Author
{
Name = "Vikash",
Gender = "Male",
Books = new List<string> { "Book4 ", "Book5" }
},
new Author
{
Name = "Nivi",
Gender = "Female",
Books = new List<string> { "Book6 ", "Book7" }
},
};
return authorList;
}
}
Example 1 : Fetch all books written by a specific Author.
Here, if we use Select operator then we will get a hierarchal result which means to print the result we will have to use two foreach blocks.
public static void Main()
{
Author author =new Author();
var BooksByVikash = author.GetAllAuthors().Where(a => a.Name == "Vikash").Select(x=>x.Books);
foreach (var books in BooksByVikash)
{
foreach(var book in books)
{
Console.WriteLine(book);
}
}
Console.ReadLine();
}
As you can see there is something weird in here, this is because we are selecting a collection from a collection means GetAllAuthors itself returns a collection of Authors , now you must be thinking we only want the books written by a particular Author then why we did not use Single() to just fetch one particular author , actually we can't do so because Select is an extension method on IEnumerable<T> which means we can use select operator with a collection of things only and not with a singleton result.
In short if there is a collection property and we are selecting that property from a collection of object then we will end up with an IEnumerable<List<T>> which is a collection of collection.
To solve the above problem we have SelectMany projection operator which enables us to project each element of a sequence to an IEnumerable<T> and flattens the resulting sequences into one sequence.
The above example can be rewritten with SelectMany operator as shown below.
public static void Main()
{
Author author =new Author();
var BooksByVikash = author.GetAllAuthors().Where(a => a.Name == "Vikash").SelectMany(x=>x.Books);
foreach (var book in BooksByVikash)
{
Console.WriteLine(book);
}
Console.ReadLine();
}
Notice the results are now flattened, and to print the result we just used one foreach block instead of two.
Example 2: Rewrite Example1 using SQL like syntax.
When using SQL like syntax style, we don't use SelectMany, instead we will have an additional from clause, which will get its data from the results of the first from clause.
Authors author= new Author();
IEnumerable<string> booksByVikash= from Author in author. GetAllAuthors ()
from Book in Author.Books
select Book;
foreach (string Book in booksByVikash)
{
Console.WriteLine(Book);
}
Output:
Select Operator
Select is a Projection Operator. Like a projector machine ,projects slides or film on to a screen , means a projector transforms one form of things into other similarly In LINQ, projection means take all or some properties of an object ,either modify them or don't modify them and project them into a new type ,same type or an anonymous type.
follow below examples for better understanding
Example 1. Projecting object property's into different Object
public class Employee
{
public int Id { get; set;}
public string Name { get; set;}
public int Phone { get; set;}
public string Gender {get;set;}
public string MaritialStatus {get;set;}
}
public class Contact
{
public int ContactId { get; set;}
public string PersonName { get; set;}
public int Phone { get; set;}
}
List<Employee> emps=new List<Employee>()
{
new Employee() {Id=1,Name="Sachin",Phone=345678901,Gender="Male", MaritialStatus ="UnMarried"},
new Employee(){Id=1,Name="Nivi",Phone=345678901, Gender="Female", MaritialStatus ="UnMarried"}
}
var contacts= emps.Select(x=> new Contact{
ContactId=x.Id,
Phone=x.Phone,
PersonName=x.Name,
}).ToList();
In the above example we are projecting Employee's properties to Contact Object which have just three properties ContactId , Phone and PersonName
Example 2.Projecting object property's into anonymous Object
public class Employee
{
public int Id { get; set;}
public string Name { get; set;}
public int Phone { get; set;}
}
List<Employee> emps=new List<Employee>()
{
new Employee() {Id=1,Name="Sachin",Phone=345678901},
new Employee(){Id=1,Name="Sachin",Phone=345678901}
}
var res= emps.Select(x=> new
{
Id=x.Id,
PhoneNumber=x.Phone,
Person=x.Name,
}).ToList();
In the above example we are projecting properties of Employee Object to an unnamed (anonymous) object , the anonymous object have three properties Id, PhoneNumber and Person.
Example 3. Projecting object property's into Same Object
public class Employee
{
public int Id { get; set;}
public string Name { get; set;}
public int Phone { get; set;}
}
List<Employee> emps=new List<Employee>()
{
new Employee() {Id=1,Name="Sachin",Phone=345678901},
new Employee(){Id=1,Name="Sachin",Phone=345678901}
}
var employees= emps.Select(x=> new Employee
{
Id=x.Id,
PhoneNumber=x.Phone,
Person=x.Name,
}).ToList();
Example 4. Projecting object property's into new Object with modification
public class Employee
{
public int Id { get; set;}
public string Name { get; set;}
public int Phone { get; set;}
public string Gender {get;set;}
public string MaritialStatus {get;set;}
}
public class Contact
{
public int ContactId { get; set;}
public string PersonName { get; set;}
public int Phone { get; set;}
}
List<Employee> emps=new List<Employee>()
{
new Employee() {Id=1,Name="Sachin",Phone=345678901,Gender="Male", MaritialStatus ="UnMarried"},
new Employee(){Id=1,Name="Nivi",Phone=345678901, Gender="Female", MaritialStatus ="UnMarried"}
}
var contacts = emps.Select(x => new Contact
{
ContactId = x.Id,
Phone = x.Phone,
PersonName =(x.Gender == "Female" && x.MaritialStatus == "Married") ? "Mrs." + x.Name : (x.Gender == "Female" && x.MaritialStatus ==
"UnMarried") ?"Ms." + x.Name: "Mr"+x.Name,
}).ToList();
Notice in the above example we are computing PersonName property of Contact class object based on the MartialStatus and Gender properties of Employee object , I have used nested ternary operatory to achieve below requirement.
• Gender="Female" and "MaritialStatus"= "Married" then Add "Mrs." prefix.
• Gender="Female" and "MaritialStatus" = UnMarried then Add "Ms." prefix else
• Add "Mr." prefix to the name property's value.
Till now what we discussed is called as Extension Method way or Method Syntax Way of writing Linq queries , all the examples can be rewritten using Sql-Like query syntaxes as shown below
Select Operator in Query Syntax
Example 1. Projecting object property's into different Object
public class Employee
{
public int Id { get; set;}
public string Name { get; set;}
public int Phone { get; set;}
public string Gender {get;set;}
public string MaritialStatus {get;set;}
}
public class Contact
{
public int ContactId { get; set;}
public string PersonName { get; set;}
public int Phone { get; set;}
}
List<Employee> emps=new List<Employee>()
{
new Employee() {Id=1,Name="Sachin",Phone=345678901,Gender="Male", MaritialStatus ="UnMarried"},
new Employee(){Id=1,Name="Nivi",Phone=345678901, Gender="Female", MaritialStatus ="UnMarried"}
}
var contacts= (from c in emps
select new Contact
{
ContactId= c.Id,
Phone= c.Phone,
PersonName= c.Name,
}).ToList();
In the above example we are projecting Employee's properties to Contact Object which have just three properties ContactId , Phone and PersonName
Example 2.Projecting object property's into anonymous Object
public class Employee
{
public int Id { get; set;}
public string Name { get; set;}
public int Phone { get; set;}
}
List<Employee> emps=new List<Employee>()
{
new Employee() {Id=1,Name="Sachin",Phone=345678901},
new Employee(){Id=1,Name="Sachin",Phone=345678901}
}
var res= (from e in emps select new
{
Id= e.Id,
PhoneNumber= e.Phone,
Person= e.Name,
}).ToList();
In the above example we are projecting properties of Employee Object to an unnamed (anonymous) object , the anonymous object have three properties Id, PhoneNumber and Person.
Example 3. Projecting object property's into Same Object
public class Employee
{
public int Id { get; set;}
public string Name { get; set;}
public int Phone { get; set;}
}
List<Employee> emps=new List<Employee>()
{
new Employee() {Id=1,Name="Sachin",Phone=345678901},
new Employee(){Id=1,Name="Sachin",Phone=345678901}
}
var employees= from e in emps select e;
Example 4. Projecting object property's into new Object with modification
public class Employee
{
public int Id { get; set;}
public string Name { get; set;}
public int Phone { get; set;}
public string Gender {get;set;}
public string MaritialStatus {get;set;}
}
public class Contact
{
public int ContactId { get; set;}
public string PersonName { get; set;}
public int Phone { get; set;}
}
List<Employee> emps=new List<Employee>()
{
new Employee() {Id=1,Name="Sachin",Phone=345678901,Gender="Male", MaritialStatus ="UnMarried"},
new Employee(){Id=1,Name="Nivi",Phone=345678901, Gender="Female", MaritialStatus ="UnMarried"}
}
var contacts= (from e in emps
select new Contact
{
ContactId = e.Id,
Phone = e.Phone,
PersonName =( e.Gender == "Female" && e.MaritialStatus == "Married") ? "Mrs." + e.Name : (e.Gender == "Female" && e.MaritialStatus ==
"UnMarried") ?"Ms." + e.Name: "Mr"+ e.Name,
}).ToList();
Notice in the above example we are computing PersonName property of Contact class object based on the MartialStatus and Gender properties of Employee object , I have used nested ternary operatory to achieve below requirement.
• Gender="Female" and "MaritialStatus"= "Married" then Add "Mrs." prefix.
• Gender="Female" and "MaritialStatus" = UnMarried then Add "Ms." prefix else
• Add "Mr." prefix to the name property's value.
Projection Operators
A projector machine ,projects slides or film on to a screen , means a projector transforms one form of things into other similarly In LINQ, projection means take all or some properties of an object ,either modify them or don't modify them and project them into a new type ,same type or an anonymous type.
follow below examples for better understanding
Example 1. Projecting object property's into different Object
public class Employee
{
public int Id { get; set;}
public string Name { get; set;}
public int Phone { get; set;}
public string Gender {get;set;}
public string MaritalStatus {get;set;}
}
public class Contact
{
public int ContactId { get; set;}
public string PersonName { get; set;}
public int Phone { get; set;}
}
List<Employee> emps=new List<Employee>()
{
new Employee() {Id=1,Name="Sachin",Phone=345678901,Gender="Male", MaritalStatus ="UnMarried"},
new Employee(){Id=1,Name="Nivi",Phone=345678901, Gender="Female", MaritalStatus ="UnMarried"}
}
var contacts= emps.Select(x=> new Contact
{
ContactId=x.Id,
Phone=x.Phone,
PersonName=x.Name,
}).ToList();
In the above example we are projecting Employee's properties to Contact Object which have just three properties ContactId , Phone and PersonName
Example 2.Projecting object property's into anonymous Object
public class Employee
{
public int Id { get; set;}
public string Name { get; set;}
public int Phone { get; set;}
}
List<Employee> emps=new List<Employee>()
{
new Employee() {Id=1,Name="Sachin",Phone=345678901},
new Employee(){Id=1,Name="Sachin",Phone=345678901}
}
var res= emps.Select(x=> new
{
Id=x.Id,
PhoneNumber=x.Phone,
Person=x.Name,
}).ToList();
In the above example we are projecting properties of Employee Object to an unnamed (anonymous) object , the anonymous object have three properties Id, PhoneNumber and Person.
Example 3. Projecting object property's into Same Object
public class Employee
{
public int Id { get; set;}
public string Name { get; set;}
public int Phone { get; set;}
}
List<Employee> emps=new List<Employee>()
{
new Employee() {Id=1,Name="Sachin",Phone=345678901},
new Employee(){Id=1,Name="Sachin",Phone=345678901}
}
var employees= emps.Select(x=> new Employee
{
Id=x.Id,
PhoneNumber=x.Phone,
Person=x.Name,
}).ToList();
Example 4. Projecting object property's into new Object with modification
public class Employee
{
public int Id { get; set;}
public string Name { get; set;}
public int Phone { get; set;}
public string Gender {get;set;}
public string MaritalStatus {get;set;}
}
public class Contact
{
public int ContactId { get; set;}
public string PersonName { get; set;}
public int Phone { get; set;}
}
List<Employee> emps=new List<Employee>()
{
new Employee() {Id=1,Name="Sachin",Phone=345678901,Gender="Male", MaritalStatus ="UnMarried"},
new Employee(){Id=1,Name="Nivi",Phone=345678901, Gender="Female", MaritalStatus ="UnMarried"}
}
var contacts = emps.Select(x => new Contact
{
ContactId = x.Id,
Phone = x.Phone,
PersonName =(x.Gender == "Female" && x.MaritalStatus == "Married") ? "Mrs." + x.Name :
(x.Gender == "Female" && x.MaritalStatus == "UnMarried") ?"Ms." + x.Name: "Mr"+x.Name,
}).ToList();
Notice in the above example we are computing PersonName property of Contact class object based on the MartialStatus and Gender properties of Employee object , I have used nested ternary operator to achieve below requirement.
• Gender="Female" and "MaritalStatus"= "Married" then Add "Mrs." prefix.
• Gender="Female" and "MaritalStatus" = UnMarried then Add "Ms." prefix else
• Add "Mr." prefix to the name property's value.
Types of LINQ Projection Operators
Linq provides us two flavours of projection operators and obviously each one have its own purpose.
• Select and
• Select many
In the coming chapters, we will learn all these Projection operators in detail with examples.