LINQ - DotNetTutorials Notes
LINQ - DotNetTutorials Notes
Uniform Query Syntax: Whether you are querying an SQL database, an XML
document, or an in-memory collection, the syntax is consistent and typically
involves query operators like where, select, groupby, etc.
Consistency: LINQ provides a consistent and uniform way to query different
data sources, simplifying code and reducing the need to learn multiple query
languages for different data types.
Improved Productivity: LINQ simplifies common data operations like filtering,
sorting, and grouping, reducing the amount of repetitive code that developers
need to write.
Strongly Typed: LINQ is strongly typed, which means the compiler checks
the syntax against the types of objects being queried, thus minimizing runtime
errors.
SQL-Like Syntax: LINQ queries use a SQL-like syntax that is familiar to many
developers, making it easier to express complex data retrieval and
manipulation operations.
LINQ Supported Data Sources:
LINQ can be used with several data sources, and there are different flavors of LINQ
based on what you are querying:
These LINQ tutorials using C# are designed for beginners and professional
developers who want to learn LINQ in C# step by step, from the very basic to the
advanced concept, using real-time examples. These tutorials provide a hands-on
approach to the subject with step-by-step program examples that will assist you in
learning and putting the acquired knowledge into practice.
To learn LINQ effectively, you should understand several foundational concepts and
technologies in the .NET framework and C# (or another .NET language that supports
LINQ, such as VB.NET). Here are the prerequisites that will help you grasp LINQ
more quickly and thoroughly:
Architecture of LINQ
In this article, I am going to discuss the Architecture of LINQ. The term LINQ stands
for Language Integrated Query, and it is pronounced as LINK. Nowadays, the use
of use LINQ is increasing rapidly. So, as a developer, you should understand LINQ
and its architecture. At the end of this article, you will have a very good
understanding of the following pointers.
1. What is LINQ?
2. Why should we learn LINQ?
3. How does LINQ work?
4. What are LINQ Providers?
5. When to Use LINQ?
6. Advantages and Disadvantages of using LINQ.
What is LINQ?
Microsoft introduced LINQ (Language Integrated Query) with .NET Framework 3.5
and C# 3.0, available in the System.Linq namespace. LINQ provides a common
syntax that allows us to query the data from various data sources in a uniform
manner. That means using a single LINQ query, we can get or set the data from
various data sources such as SQL Server database, XML documents, ADO.NET
Datasets, and any other in-memory objects such as Collections, Generics, etc.
Let us understand why we should learn LINQ with an example. Suppose we are
developing a .NET Application that requires data from different sources. For example
1. The application needs data from the SQL Server Database. So, as a
developer, to access the data from the SQL Server Database, we need to
understand ADO.NET and SQL Server-specific syntaxes. We need to learn
SQL Syntax specific to Oracle Database if the database is Oracle.
2. The application also needs data from an XML Document. So, as a developer,
to work with XML documents, we need to understand XPath
and XSLT queries.
3. The application also needs to manipulate the data (objects) in memory, such
as List<Products>, List<Orders>, etc. So, as a developer, we should also
understand how to work with in-memory objects.
LINQ provides a Uniform Programming Model (i.e., Common Query Syntax), which
allows us to work with different data sources such as databases, XML Documents,
in-memory objects, etc., but using a standard or, you can say, unified coding style.
As a result, we are not required to learn different syntaxes to query different data
sources.
Please look at the following diagram to understand how the LINQ works in the .NET
Framework.
As shown in the above diagram, you can write the LINQ queries using any DOT NET
Supported Programming Language such as C#, VB.NET, J#, F#, etc.
The LINQ Provider is a software component that sits between the LINQ Queries and
the Data Source. The LINQ provider will convert the LINQ queries into a format that
the underlying data source can understand. For example, LINQ to SQL provider will
convert the LINQ queries to SQL statements, which the SQL Server database can
understand. Similarly, the LINQ to XML provider will convert the queries into a format
the XML document can understand.
What are LINQ Providers?
LINQ (Language Integrated Query) providers are components that enable querying
against a specific data source using the LINQ syntax in .NET. LINQ providers are
components or libraries responsible for translating LINQ queries into a format that the
underlying data sources can execute.
The beauty of LINQ is its ability to provide a consistent querying experience across
different types of data sources, but it achieves this through using various LINQ
providers. Each provider is designed to work with a particular type of data source or a
particular way of accessing data.
Translation of LINQ Queries: LINQ providers translate LINQ queries into the
native query language of the data source. For example, a LINQ provider for
SQL Server translates LINQ queries into T-SQL queries.
Different Providers for Different Data Sources: Different LINQ providers
exist for different data sources. Some common ones include:
LINQ to Objects: Used for querying in-memory collections like arrays or
lists.
LINQ to SQL (DLinq): Used for querying SQL Server databases.
LINQ to Entities (Entity Framework): Used for querying databases via
the Entity Framework, which supports multiple database types.
LINQ to XML (XLinq): Used for querying XML documents.
Custom Providers: Developers can create custom LINQ providers to enable
LINQ querying over custom data sources, like a proprietary database or a
unique data format.
Execution of Queries: The LINQ provider executes the query against the
data source and returns the results. This execution can involve translating the
query into a different format, executing it, and then materializing the results
back into .NET objects.
Performance Considerations: The efficiency of LINQ queries can depend
heavily on the specific LINQ provider used, as different providers have
different ways of translating and executing queries.
Different Ways to Write LINQ Queries in C#:
Query Syntax: It is similar to SQL and is often more readable for those familiar with
SQL. It starts with a from clause followed by a range variable and includes standard
query operations like where, select, group, join, etc.
Knowing when to use LINQ is important for writing clean, efficient, and maintainable
code. Here are some scenarios where LINQ is particularly useful:
Querying Collections: LINQ is ideal for querying collections like arrays, lists,
or any other types that implement IEnumerable. It simplifies the process of
filtering, sorting, and grouping data.
Database Operations: With LINQ to SQL or Entity Framework, you can
perform database operations. LINQ queries are automatically translated into
SQL queries, making it easier to interact with databases without writing raw
SQL.
Readability and Maintainability: LINQ queries often result in more readable
and maintainable code compared to traditional loops and conditional
statements. The syntax is declarative, specifying what you want to do rather
than how to do it.
Working with XML: LINQ to XML provides a simple and efficient way to
handle XML documents. It allows you to query, modify, and navigate XML data
in a more readable and concise way.
Joining Data Sources: If you need to join data from different sources (like
different collections, databases, or XML files), LINQ can be a powerful tool. It
simplifies the syntax for joining and correlating data from multiple sources.
Aggregations and Calculations: When you need to perform calculations or
aggregations (like sum, average, min, max) on a collection of items, LINQ
offers straightforward methods to accomplish these tasks.
Converting Data Types: LINQ provides easy-to-use methods for converting
one type of data into another, such as converting an array to a list or vice
versa.
What are the Advantages of using LINQ?
1. We don’t need to learn new query language syntaxes for different data
sources as it provides common query syntax to query different data sources.
2. Less code as compared to the traditional approach. That means by using
LINQ, we can minimize our code.
3. It provides Compile-time error checking as well as intelligence support in
Visual Studio. This powerful feature helps us to avoid run-time errors.
4. LINQ provides many inbuilt methods that we can use to perform different
operations such as filtering, ordering, grouping, etc., which makes our work
easy.
5. Its query can be reused.
What are the Disadvantages of using LINQ?
A query is nothing but a set of instructions applied to a data source (i.e., In-Memory
Objects, SQL Server, XML Document, etc.) to perform certain operations (i.e., CRUD
operations) and then tells the shape of the output from that query. That means the
query is not responsible for what will be the output rather, it is responsible for the
shape of the output. This also means what will return from that query, whether it will
return a particular value, a particular list, or an object. Each query is a combination of
three things. They are as follows:
1. Query Syntax
2. Method Syntax
3. Mixed Syntax (Query + Method)
Note: From the performance point of view, there is no difference between the above
three approaches. So, which you need to use totally depends on your personal
preference. But the point that you need to keep in mind is, behind the scenes, the
LINQ queries written using query syntax are translated into their lambda expressions
before they are compiled.
LINQ Query Syntax:
Query Syntax is more similar to SQL, providing a readable and declarative way of
writing queries. Under the hood, it gets translated into Method Syntax at compile
time. This is one of the easy ways to write complex LINQ queries in an easy and
readable format. If you are familiar with SQL Queries, it will be easy for you to write
LINQ queries using this query syntax. The syntax is given below.
Characteristics:
Method Syntax (also known as Fluent Syntax or Lambda Syntax) uses extension
methods included in the System.Linq namespace and can be chained together to
perform complex queries. It is similar to calling methods in a traditional object-
oriented programming language. Method syntax has become most popular
nowadays for writing LINQ queries. In this approach, the LINQ query is written using
multiple methods by combining them with a dot (.), i.e., method chaining. The Syntax
is given below:
Characteristics:
Utilizes lambda expressions.
It can be more concise for complex queries.
Offers slightly more methods and flexibility than Query Syntax.
It can be easier to understand for those familiar with lambda expressions and
functional programming.
LINQ Mixed Syntax:
You can also mix both syntaxes, although this is less common. This is the
combination of both Query and Method syntax. The syntax is given below.
using System;
using System.Collections.Generic;
using System.Linq;
namespace LINQDemo
{
class Program
{
static void Main(string[] args)
{
//Step1: Data Source
List<int> integerList = new List<int>()
{
1, 2, 3, 4, 5, 6, 7, 8, 9, 10
};
//Step2: Query
//LINQ Query using Query Syntax to fetch all
numbers which are > 5
var QuerySyntax = from obj in integerList
//Data Source
where obj > 5 //Condition
select obj; //Selection
//Step3: Execution
foreach (var item in QuerySyntax)
{
Console.Write(item + " ");
}
Console.ReadKey();
}
}
}
Now run the application, and it will display the values 6 7 8 9 10 as expected in the
console window. Let us understand what we did in the above code.
using System;
using System.Collections.Generic;
using System.Linq;
namespace LINQDemo
{
class Program
{
static void Main(string[] args)
{
//Step1: Data Source
List<int> integerList = new List<int>()
{
1, 2, 3, 4, 5, 6, 7, 8, 9, 10
};
//Step2: Query
//LINQ Query using Query Syntax to fetch all
numbers which are > 5
var QuerySyntax = integerList.Where(obj => obj
> 5).ToList();
//Step3: Execution
foreach (var item in QuerySyntax)
{
Console.Write(item + " ");
}
Console.ReadKey();
}
}
}
Now, run the application, and you will get the output as expected. Let us have a look
at the following diagram to understand Method Syntax.
Example Using LINQ Mixed Syntax in C#:
Let us change our requirements. First, we need to filter the list where the value is
greater than 5, and then we need to calculate the sum.
using System;
using System.Collections.Generic;
using System.Linq;
namespace LINQDemo
{
class Program
{
static void Main(string[] args)
{
//Data Source
List<int> integerList = new List<int>()
{
1, 2, 3, 4, 5, 6, 7, 8, 9, 10
};
//LINQ Query using Mixed Syntax
var MethodSyntax = (from obj in integerList
where obj > 5
select obj).Sum();
//Execution
Console.Write("Sum Is : " + MethodSyntax);
Console.ReadKey();
}
}
}
Now, run the application, and you will see the output as expected. Let us understand
what we did in the above code by looking at the following image.
When should you use the LINQ Method and Query Syntax?
In the .NET framework, LINQ (Language Integrated Query) provides two main ways
to write queries: Method syntax and Query syntax. Both syntaxes can be used to
perform a wide range of operations, such as filtering, sorting, and grouping, but there
are some differences in how they are used and in their capabilities.
Let us understand these two interfaces with examples. Please look at the following
program we wrote using the LINQ Query Syntax in our previous article.
In the above example, we use the var keyword to create the variable and store the
result of the LINQ query. So, let’s check what the type of variable is. To check this,
just mouse over the pointer onto the QuerySynntax variable, and you will see that the
type is IEnumerable<int>, which is a generic type. So, it is important to understand
what is IEnumerable<T>.
So, in the above example, instead of writing the var keyword, you can also
write IEnumerable<int>, and it should work as expected, as shown in the below
example.
using System;
using System.Collections.Generic;
using System.Linq;
namespace LINQDemo
{
class Program
{
static void Main(string[] args)
{
List<int> integerList = new List<int>()
{
1, 2, 3, 4, 5, 6, 7, 8, 9, 10
};
IEnumerable<int> QuerySyntax = from obj in
integerList
where obj > 5
select obj;
foreach (var item in QuerySyntax)
{
Console.Write(item + " ");
}
Console.ReadKey();
}
}
}
With this kept in mind, let us understand what IEnumerable is.
Whenever we want to work with in-memory objects, we need to use the IEnumerabe
interface, and the reason for this will be discussed in our next article. In the below
example, we have a complex type called Student. Within the Main method, we
created a collection to hold a list of students. Then, we are required to display only
the Male students. For this, we are using the LINQ Query to fetch the Male students
from the student collection data source, and then using a for each loop, we are
iterating through the IEnumerable<Student> collection.
using System;
using System.Collections.Generic;
using System.Linq;
namespace LINQDemo
{
class Program
{
static void Main(string[] args)
{
List<Student> studentList = new List<Student>()
{
new Student(){ID = 1, Name = "James", Gender =
"Male"},
new Student(){ID = 2, Name = "Sara", Gender =
"Female"},
new Student(){ID = 3, Name = "Steve", Gender =
"Male"},
new Student(){ID = 4, Name = "Pam", Gender =
"Female"}
};
//Linq Query to Fetch all students with Gender
Male
IEnumerable<Student> QuerySyntax = from std in
studentList
where std.Gender == "Male"
select std;
//Iterate through the collection
foreach (var student in QuerySyntax)
{
Console.WriteLine( $"ID : {student.ID} Name :
{student.Name}");
}
Console.ReadKey();
}
}
public class Student
{
public int ID { get; set; }
public string Name { get; set; }
public string Gender { get; set; }
}
}
When we execute the program, the result will be displayed as expected, as shown in
the image below.
Deferred Execution: IQueryable defers the execution of the query until the
queryable object is actually iterated over. This means the query is not
executed when defined but when the results are required.
Expression Trees: IQueryable queries are represented as expression trees.
An expression tree is a data structure that represents code in a tree-like
format, where each node is an expression, such as a method call or a binary
operation. This allows the query to be translated into a format that can be
understood by the data source, such as SQL for a database.
Query Providers: IQueryable relies on an implementation of the
IQueryProvider interface to execute queries. The provider translates the
expression tree into a format that can be executed against the data source.
Key Characteristic of IQueryable in C#:
using System;
using System.Collections.Generic;
using System.Linq;
namespace LINQDemo
{
class Program
{
static void Main(string[] args)
{
List<Student> studentList = new List<Student>()
{
new Student(){ID = 1, Name = "James", Gender =
"Male"},
new Student(){ID = 2, Name = "Sara", Gender =
"Female"},
new Student(){ID = 3, Name = "Steve", Gender =
"Male"},
new Student(){ID = 4, Name = "Pam", Gender =
"Female"}
};
//Linq Query to Fetch all students with Gender
Male
IQueryable<Student> MethodSyntax =
studentList.AsQueryable()
.Where(std => std.Gender == "Male");
//Iterate through the collection
foreach (var student in MethodSyntax)
{
Console.WriteLine( $"ID : {student.ID} Name :
{student.Name}");
}
Console.ReadKey();
}
}
public class Student
{
public int ID { get; set; }
public string Name { get; set; }
public string Gender { get; set; }
}
}
Now run the application, and you will see the data as expected, as shown in the
below image.
The point you need to remember is to return a collection of IQueryable type and call
the AsQueryable() method on the data source, as we did in the above example.
Use IEnumerable when working with in-memory data collections where the
data set is not excessively large.
Use IQueryable when querying data from out-of-memory sources like
databases, especially when dealing with large data sets, to take advantage of
server-side processing and optimizations.
In the next article, I will discuss the Differences Between IEnumerable and
IQueryable in C# and when to use one over another with an example. I hope this
article gives you a good understanding of two important interfaces, i.e., IEnumerable
and IQueryable in C# with Examples.
The IEnumerable and IQueryable in C# are used to hold a collection of data and also
to perform data manipulation operations such as filtering, ordering, grouping, etc.,
based on the business requirements. This article will show you the difference
between IEnumerable and IQueryable in C# with Examples. For a better
understanding, please have a look at the following image. As you can see,
IEnumerable<T> fetches the record from the database without applying the filter. But
IQueryable<T> fetches the record from the database by applying the filter.
Advertisements
In this demo, we will create a Console Application to retrieve the data from the SQL
Server database using the Entity Framework Database First approach. We are going
to fetch the following Student information from the Student table.
Please use the SQL script below to create and populate the Student table with the
required test data.
Let us modify the Main method of the Program class as shown below. In the example
below, we are fetching the top 2 students from the Students table where the gender
is male. But we have split the LINQ query into two statements. The first statement
contains the where method, and the second statement contains the Take method.
Then, using a for each loop, we display the top 2 student information. Further, to see
what SQL Statement was generated and executed on the database by Entity
Framework, we are using DBContext.Database.Log = Console.Write statement
that will log the SQL Script on the Console window.
using System;
using System.Collections.Generic;
using System.Linq;
namespace LINQDemo
{
class Program
{
static void Main(string[] args)
{
using (StudentDBContext DBContext = new
StudentDBContext())
{
//To See What SQL Generated By Entity Framework
DBContext.Database.Log = Console.Write;
//Fetch the Top 2 Records from the Students
Database table where Gender = Male
IEnumerable<Student> listStudents =
DBContext.Students.Where(x => x.Gender ==
"Male");
listStudents = listStudents.Take(2);
Console.WriteLine("Top 2 Student Where Gender =
Male");
foreach (var std in listStudents)
{
Console.WriteLine(std.FirstName + " " +
std.LastName);
}
}
Console.ReadKey();
}
}
}
Here, we create the LINQ Query using IEnumerable. With the above code in
place, run the application and see the output. You should get the following
output.
As you can see in the above SQL Script, it will not use the TOP clause. So, here, it
will fetch all the Male Students from SQL Server to in-memory, and then it will filter
the data in memory.
Let us modify the Main method of the Program class as shown below to use
IQueryable. The following example does the same thing as the previous one, but
here, we store the query in a variable of IQueryable<Student> type. For this, we are
using the AsQueryable() method. We are also logging the generated SQL Statement
on the Console window.
using System;
using System.Linq;
namespace LINQDemo
{
class Program
{
static void Main(string[] args)
{
using (StudentDBContext DBContext = new
StudentDBContext())
{
//To See What SQL Generated By Entity Framework
DBContext.Database.Log = Console.Write;
//Fetch the Top 2 Records from the Students
Database table where Gender = Male
IQueryable<Student> listStudents =
DBContext.Students
.AsQueryable()
.Where(x => x.Gender == "Male");
listStudents = listStudents.Take(2);
Console.WriteLine("Top 2 Student Where Gender =
Male");
foreach (var std in listStudents)
{
Console.WriteLine(std.FirstName + " " +
std.LastName);
}
}
Console.ReadKey();
}
}
}
Here, we create the LINQ Query using IQueryable. With the above changes in
place, now run the application and see the output. You should get the
following output.
AD
As you can see in the above image, it includes the TOP (2) clause in the SQL Script
and then fetches the data from the database. That means the filtering is now
happening on the database side. With this in mind, let us discuss the differences
between IEnumerable and IQueryable in C#.
Namespace:
IEnumerable: LINQ methods are executed in memory on the entire data set.
Filtering, sorting, and other operations are performed locally.
IQueryable: LINQ methods are translated into a query language specific to the
data source (e.g., SQL) and executed on the data source. This allows for
efficient server-side operations.
Suitable Use Cases:
1. Use IEnumerable for in-memory data collections or when dealing with small
data sets.
2. Use IQueryable when querying large data sets or remote data sources like
databases, especially when you need efficient querying and data retrieval.
In the next article, I will discuss the LINQ Extension Methods in C# with Examples.
In this article, I explain the Differences Between IEnumerable and IQueryable in
C#. I hope this article gives you a very good understanding of the Differences
Between IEnumerable and IQueryable in C# with Examples.
The LINQ’s standard query operators, such as select, where, etc., are implemented
in the Enumerable class. These methods are implemented as extension methods of
the type IEnumerable<T> interface. Let us understand this with an example. We
have the following code in our Main method.
The above Where() method does not belong to the List<T> class, but still, we can
call it as it belongs to the List<T> class. Why can it be called using
the List<T> object? Let’s find out. If you go to the definition of the Where method,
then you will find the following definition.
As you can see in the signature, the where Where() method is implemented as an
extension method on the IEnumerable<T> interface, and we
know List<T> implements the IEnumerable<T> interface. This is the reason why we
can call the Where() method using the List<T> object. With this in mind, let us
understand what extension methods are and how they are implemented in C#.
In simple words, we can say that the Extension methods can be used as an
approach to extending the functionality of a class by adding new methods into the
existing class if the source code of the class is not available or if we don’t have any
permission in making changes to the existing class.
The most important point you need to remember is that extension methods are the
static methods of a static class, but they will be called as if they were instance
methods on the extended type.
You need to use an extension method if any of the following conditions are true:
1. You need a method on an existing type, and you are not the owner of the
source code of that type.
2. You need a method on an existing type; you do not own the source code of
that type, but that type is an interface.
3. You need a method on an existing type, you do not own the source code, and
that type is not an interface, but adding the method creates undesired
coupling.
Otherwise, you should go with the normal method of the actual type itself.
Let us understand this with an example. Our requirement is that we want to add a
method in the built-in string class. Let’s call this method GetWordCount(), which will
count the word present in a string separated by a space.
For example, if the string is “Welcome to Dotnet Tutorials,” it should return the word
count as 4. The most important point is that we need to call this method on the String
object, as shown below.
int wordCount = sentence.GetWordCount();
Note: We cannot define the GetWordCount() method directly in the string class as
we do not own the string class. The string class belongs to the System namespace,
owned by the .NET framework. So, the alternative solution to achieve this is to write
a wrapper class, as shown below.
Now, let’s convert the GetWordCount() method to an extension method on the String
class. So that we can able to call the GetWordCount() method using the following
syntax.
int wordCount = sentence.GetWordCount();
using System;
namespace LINQDemo
{
class Program
{
static void Main(string[] args)
{
string sentence = "Welcome to Dotnet
Tutorials";
int wordCount = sentence.GetWordCount();
Console.WriteLine($"Count : {wordCount}");
Console.ReadKey();
}
}
public static class ExtensionHelper
{
public static int GetWordCount(this string str)
{
if (!String.IsNullOrEmpty(str))
return str.Split(' ').Length;
return 0;
}
}
}
Now run the application, and you will see the word count as expected in the console
window. Here, we can still call the GetWordCount() extension method using the
wrapper class style syntax and get the output as expected, as shown below.
So, the point that I need to keep focus on is that this is how the extension methods
are called internally behind the scenes.
That means it is also possible to call the LINQ extension methods such as select,
where, etc., using the wrapper class style syntax. As all the LINQ extension
methods are implemented in the Enumerable class, the syntax to call those
methods should look as shown below.
using System;
using System.Collections.Generic;
using System.Linq;
namespace LINQDemo
{
class Program
{
static void Main(string[] args)
{
List<int> intList = new List<int> { 1, 2, 3, 4,
5, 6, 7, 8, 9, 10 };
IEnumerable<int> EvenNumbers =
Enumerable.Where(intList, n => n % 2 == 0);
Console.ReadKey();
}
}
}
LINQ Extension Method in C#:
Intersect / Except / Union: Performs set operations like intersection, difference, and
union on sequences.
var commonElements = collection1.Intersect(collection2);
In the next article, I will discuss the LINQ Operators in C# with Examples. In this
article, I try to explain the Linq Extension Methods in C# with Examples. I hope you
enjoy this LINQ Extension Methods in C# article.
The LINQ Operators are nothing but a set of extension methods used to write the
LINQ Query. These LINQ extension methods provide many useful features we can
apply to the data source. Some of the features are filtering the data, sorting the data,
grouping the data, etc.
Projection Operators:
These operators transform the elements of a sequence into a new form. Common
projection operators include Select and SelectMany.
These operators divide a sequence into two parts and return one of them. Examples
include Take, Skip, TakeWhile, and SkipWhile.
These operators group elements of a sequence based on a specified key value. The
most notable grouping operator is GroupBy.
These operators are used to combine elements from two or more sequences.
Common join operators are Join and GroupJoin.
These are used to convert one type of sequence or collection to another. Examples
include ToArray, ToList, ToDictionary, and AsEnumerable.
These operators return a single element from a sequence. Examples include First,
FirstOrDefault, Last, LastOrDefault, Single, SingleOrDefault, and ElementAt.
These operators return a Boolean value indicating whether all or any of the elements
of a sequence satisfy a condition. Examples are All, Any, and Contains.
These operators are used to create a new sequence of values. Examples include
Range, Repeat, and Empty.
1. What is Projection?
2. What are Projection Operators and Methods Available in LINQ?
3. How do you use the LINQ Select Method or Select Operator?
4. Examples to Understand Basic Projection of Data to the Same Type.
5. How do you project data to different Classes and Anonymous Types?
6. Performing Calculations on the Selected data using LINQ Select
Operator.
7. How to Select Data with Index Value?
8. When should you use the LINQ Select Method in C#?
Note: We will discuss each example using LINQ Query and Method Syntax. Again,
when I am saying LINQ Operator or Method, the meaning is going to be same.
Projection in LINQ is nothing but a mechanism used to select the data from a data
source. You can select the data in the same form (i.e., the original form). It is also
possible to create a new form of data by performing some operations on it. So, in
simple words, we can say that Projection is an operation that converts an object into
a new form that holds only those properties as per our requirements.
What are Projection Methods or Operators Available in LINQ?
There are two methods available in the projection operator category in LINQ. They
are as follows.
1. Select
2. SelectMany
In this article, we will discuss the LINQ Select Method with Examples, and in the
next article, we will discuss the LINQ SelectMany Method with Examples.
The LINQ Select Projection Operator or Method can be used to format the query’s
result as per our requirement. The LINQ Select Operator can return a scaler value, a
custom class, a collection of custom classes, or an anonymous type, which includes
properties per our business requirements.
The Select Clause in SQL allows us to specify what columns we want to retrieve.
Whether we want to retrieve all the columns or some of the columns that we need to
specify in the select clause of the SQL Statement. In the same way, the LINQ Select
operator allows us to specify what properties we want to retrieve. We need to specify
whether we want to retrieve all or some of the properties in the Select Operator. The
LINQ Select Method also allows us to perform some calculations.
Let us understand the LINQ Select Projection Operator with Examples using C#
Language. Here, we are going to use a Console Application. So first, create a
console application named LINQDemo (you can give any meaningful name). Then,
add a new class file with the name Employee.cs. Once you add
the Employee.cs class file, copy and paste the following code.
using System.Collections.Generic;
namespace LINQDemo
{
public class Employee
{
public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int Salary { get; set; }
public static List<Employee> GetEmployees()
{
List<Employee> employees = new List<Employee>
{
new Employee {ID = 101, FirstName = "Preety",
LastName = "Tiwary", Salary = 60000 },
new Employee {ID = 102, FirstName = "Priyanka",
LastName = "Dewangan", Salary = 70000 },
new Employee {ID = 103, FirstName = "Hina",
LastName = "Sharma", Salary = 80000 },
new Employee {ID = 104, FirstName = "Anurag",
LastName = "Mohanty", Salary = 90000 },
new Employee {ID = 105, FirstName = "Sambit",
LastName = "Satapathy", Salary = 100000 },
new Employee {ID = 106, FirstName = "Sushanta",
LastName = "Jena", Salary = 160000 }
};
return employees;
}
}
}
As you can see, we created the Employee class with the four properties: ID,
FirstName, LastName, and Salary. We also created one static method to return the
hard-coded list of employees, which will act as our data source. Let us discuss some
examples to understand the LINQ Select Operator. The point that you need to
remember is that while using the Query Syntax, I will use the term Select as
Operator, and while using the Method Syntax, I will use the term Select as Method.
Select all the Employee data from the data source using both the LINQ Method and
Query Syntax. Please look at the following image, which shows Query and Method
Syntax to fetch all the Employees. The following image is self-explained. You need to
remember that it is not executed when we form the query. When we call the ToList()
Method, Sum() Method, etc., or use the Query variable within a for-each loop, only
the Query will be executed.
Modify the Main Method of the Program class as follows. In the below code, we are
using the Select Method and Select Operator to return the data in its original shape.
That means the return data shape will be identical to the Student class shape (i.e.,
the same properties).
using System;
using System.Collections.Generic;
using System.Linq;
namespace LINQDemo
{
class Program
{
static void Main(string[] args)
{
//Using Query Syntax
List<Employee> basicQuery = (from emp in
Employee.GetEmployees()
select emp).ToList();
foreach (Employee emp in basicQuery)
{
Console.WriteLine($"ID : {emp.ID} Name :
{emp.FirstName} {emp.LastName}");
}
//Using Method Syntax
IEnumerable<Employee> basicMethod =
Employee.GetEmployees().ToList();
foreach (Employee emp in basicMethod)
{
Console.WriteLine($"ID : {emp.ID} Name :
{emp.FirstName} {emp.LastName}");
}
Console.ReadKey();
}
}
}
How do you Select a Single Property using LINQ Select Operator
or Method in C#?
In our previous example, we returned the data in its original form, i.e., returning all
the properties of the Student class. We don’t want to return all the properties; we
want to return a single property value. Our requirement is to Select all the Employee
IDs using the LINQ Method and Query syntax. In that case, we need to specify the ID
property within the Select Operator or Method as follows:
Note: In the Query Syntax, the data type of the basicPropQuery variable
is List<int>. This is because of the ToList() method applied to the Query Syntax. And
because of this ToList() method, the query is executed at that point only.
But in the case of Method Syntax, we have not applied the ToList() method, which is
why the data type of the basicPropMethod variable is of IEnumerable<int> type.
And more importantly, at that point, the query is generated but not executed. When
we use the basicPropMethod variable within the for-each loop, the query will be
executed at that time.
Iteration: The Select operator iterates over each element in the source
sequence.
Transformation: For each element, it applies the transformation logic defined
in the lambda expression.
Result: It produces a new sequence where each element is the result of the
applied transformation on the corresponding element from the source
sequence.
Deferred Execution: An important aspect of the Select operator in LINQ is that it
uses deferred execution. This means that the actual transformation of elements
doesn’t happen when you define the Select call but when you iterate over the
resulting sequence. This can be important for performance, especially with large data
sets or complex queries.
We have discussed selecting all the properties and a single property using LINQ
Select Projection Operator and Method. Now, let us proceed and try to understand
how to select a few properties using LINQ Select Projection Operator and Method
with an example.
Our requirement is to select only the Employee’s First Name, Last Name, and Salary
properties. We don’t want to select the employee’s ID property. For a better
understanding, please have a look at the following image. In the code below, we
select the First Name, Last Name, and Salary properties of the same Employee
class. Later, I will show you how to project these properties to a different class and
an anonymous type. With the Select Operator or Method, we create an instance of
the Employee class and populate the First Name, Last Name, and Salary properties
from the data source which we can access using the emp object.
using System;
using System.Collections.Generic;
using System.Linq;
namespace LINQDemo
{
class Program
{
static void Main(string[] args)
{
//Query Syntax
IEnumerable<Employee> selectQuery = (from emp
in Employee.GetEmployees()
select new Employee()
{
FirstName = emp.FirstName,
LastName = emp.LastName,
Salary = emp.Salary
});
foreach (var emp in selectQuery)
{
Console.WriteLine($" Name : {emp.FirstName}
{emp.LastName} Salary : {emp.Salary} ");
}
//Method Syntax
List<Employee> selectMethod =
Employee.GetEmployees().
Select(emp => new Employee()
{
FirstName = emp.FirstName,
LastName = emp.LastName,
Salary = emp.Salary
}).ToList();
foreach (var emp in selectMethod)
{
Console.WriteLine($" Name : {emp.FirstName}
{emp.LastName} Salary : {emp.Salary} ");
}
Console.ReadKey();
}
}
}
How do you Select a Few Properties to a Different class using a
LINQ Select Operator?
It is also possible to project or select the data to a different class using the LINQ
Select Operator or Method. In our previous example, we have seen how to select a
few properties (First Name, Last Name, and Salary properties) to the same class
using the LINQ Select Projection Operator. Let us create a new class with the above
three properties, and we will project the data to this class. So, please create a new
class file named EmployeeBasicInfo.cs and copy and paste the following code.
namespace LINQDemo
{
public class EmployeeBasicInfo
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Salary { get; set; }
}
}
We need to select the First Name, Last Name, and Salary properties to the above
newly created EmployeeBasicInfo class. For a better understanding, please have a
look at the below image. Now, with the Select Method or Operator, we are not
creating an instance of the Employee class. We are creating an instance of the
EmployeeBasicInfo class and populating the FirstName, LastName, and Salary
properties from the data source we can access using the emp object.
Advertisements
AD
using System;
using System.Collections.Generic;
using System.Linq;
namespace LINQDemo
{
class Program
{
static void Main(string[] args)
{
//Query Syntax
IEnumerable<EmployeeBasicInfo> selectQuery =
(from emp in Employee.GetEmployees()
select new EmployeeBasicInfo()
{
FirstName = emp.FirstName,
LastName = emp.LastName,
Salary = emp.Salary
});
foreach (var emp in selectQuery)
{
Console.WriteLine($" Name : {emp.FirstName}
{emp.LastName} Salary : {emp.Salary} ");
}
//Method Syntax
List<EmployeeBasicInfo> selectMethod =
Employee.GetEmployees().
Select(emp => new EmployeeBasicInfo()
{
FirstName = emp.FirstName,
LastName = emp.LastName,
Salary = emp.Salary
}).ToList();
foreach (var emp in selectMethod)
{
Console.WriteLine($" Name : {emp.FirstName}
{emp.LastName} Salary : {emp.Salary} ");
}
Console.ReadKey();
}
}
}
How do you project the data to Anonymous Type using LINQ
Select Operator/Method?
using System;
using System.Collections.Generic;
using System.Linq;
namespace LINQDemo
{
class Program
{
static void Main(string[] args)
{
//Query Syntax
var selectQuery = (from emp in
Employee.GetEmployees()
select new
{
FirstName = emp.FirstName,
LastName = emp.LastName,
Salary = emp.Salary
});
foreach (var emp in selectQuery)
{
Console.WriteLine($" Name : {emp.FirstName}
{emp.LastName} Salary : {emp.Salary} ");
}
//Method Syntax
var selectMethod = Employee.GetEmployees().
Select(emp => new
{
FirstName = emp.FirstName,
LastName = emp.LastName,
Salary = emp.Salary
}).ToList();
foreach (var emp in selectMethod)
{
Console.WriteLine($" Name : {emp.FirstName}
{emp.LastName} Salary : {emp.Salary} ");
}
Console.ReadKey();
}
}
}
How do you Perform Calculations on Selected Data using the
LINQ Select Operator?
Let me first explain what we want to achieve. We want to perform the following
calculations on the selected employee data. We need to calculate the Annual Salary
and merge the First and Last Name as Full Name in the output.
1. AnnualSalary = Salary*12
2. FullName = FirstName + ” ” + LastName
Once we do the above calculation, we need to project the ID, AnnualSalary, and
FullName to an anonymous type using the LINQ Projection Operator. For a better
understanding, please have a look at the following image.
The Complete Example Code is Given Below.
using System;
using System.Collections.Generic;
using System.Linq;
namespace LINQDemo
{
class Program
{
static void Main(string[] args)
{
//Query Syntax
var selectQuery = (from emp in
Employee.GetEmployees()
select new
{
EmployeeId = emp.ID,
FullName = emp.FirstName + " " + emp.LastName,
AnnualSalary = emp.Salary * 12
});
foreach (var emp in selectQuery)
{
Console.WriteLine($" ID {emp.EmployeeId} Name :
{emp.FullName} Annual Salary :
{emp.AnnualSalary} ");
}
//Method Syntax
var selectMethod = Employee.GetEmployees().
Select(emp => new
{
EmployeeId = emp.ID,
FullName = emp.FirstName + " " + emp.LastName,
AnnualSalary = emp.Salary * 12
}).ToList();
foreach (var emp in selectMethod)
{
Console.WriteLine($" ID {emp.EmployeeId} Name :
{emp.FullName} Annual Salary :
{emp.AnnualSalary} ");
}
Console.ReadKey();
}
}
}
How do you Select Data with Index Value using LINQ Select
Projection Operator?
It is also possible to select values using an integral index. The index is 0 based. The
index will be from 0 to 4 if the query fetches five records. It’s a unique value to each
record we select or project from the data source.
using System;
using System.Linq;
namespace LINQDemo
{
class Program
{
static void Main(string[] args)
{
//Query Syntax
var query = (from emp in
Employee.GetEmployees().Select((value, index)
=> new { value, index })
select new
{
//Index is 0-Based, and always increases by 1
IndexPosition = emp.index,
FullName = emp.value.FirstName + " " +
emp.value.LastName,
emp.value.Salary
}).ToList();
foreach (var emp in query)
{
Console.WriteLine($" Position
{emp.IndexPosition} Name : {emp.FullName}
Salary : {emp.Salary} ");
}
//Method Syntax
//Projects each element of a sequence into a
new form by incorporating the element's index.
var selectMethod = Employee.GetEmployees().
Select((emp, index) => new
{
//Index is 0-Based, and always increases by 1
IndexPosition = index,
FullName = emp.FirstName + " " + emp.LastName,
emp.Salary
});
foreach (var emp in selectMethod)
{
Console.WriteLine($" Position
{emp.IndexPosition} Name : {emp.FullName}
Salary : {emp.Salary} ");
}
Console.ReadKey();
}
}
}
When should you use the LINQ Select Operator in C#?
The Select operator projects each sequence element into a new form. This is
analogous to the SELECT statement in SQL, which picks out specific columns of
data from a table. Here are several scenarios when you might use it: