Language INtegrated Query or LINQ is a .NET technology gives the capability to query data from various data sources such as .NET collections, XML documents, SQL databases, ADO.NET datasets. LINQ is integrated with C# and VB.NET and the query construct and syntax is the same no matter which data source you are querying.
You can use LINQ with any collection that exposes IEnumerable
or IEnumerable<T>
interface. LINQ queries can be written in two ways - using query syntax or method syntax. The following example shows a simple LINQ query on a custom collection of class objects.
class Car { public string Make { get; set; } public string Model { get; set; } public int Year { get; set; } public string Transmission { get; set; } public string FuelType { get; set; } } List<Car> Cars = new List<Car>() { new Car {Make = "BMW", Model = "3 Series", Year = 2018, Transmission = "Manual", FuelType = "Petrol"}, new Car {Make = "Mercedes-Benz", Model = "E Class", Year = 2017, Transmission = "Automatic", FuelType = "Petrol"}, new Car {Make = "Audi", Model = "Q7", Year = 2020, Transmission = "Automatic", FuelType = "Diesel"}, new Car {Make = "Toyota", Model = "Auris", Year = 2015, Transmission = "Automatic", FuelType = "Hybrid"}, new Car {Make = "Ford", Model = "Focus", Year = 2013, Transmission = "Manual", FuelType = "Petrol"}, }; // LINQ Query to get all cars in Query Syntax var queryAllCars = from car in Cars select car; // queryAllCars is IEnumerable<car> foreach (var car in queryAllCars) { Console.WriteLine($"{car.Make} - {car.Model} "); }
Output:
BMW - 3 Series Mercedes-Benz - E Class Audi - Q7 Toyota - Auris Ford - Focus
In the above example the LINQ query was written in query syntax. The same can be achieved using method syntax as below.
var queryAllCars = Cars.Select(car => car);
In method systax, you call the select
method and pass a lambda expression(car => car
) as parameter
Note that performance-wise there is no difference between query syntax and method syntax. Query syntax is more readable while some operations can be done only using method syntax.
Rest of this article shows you examples of how to use LINQ methods to perform various operations on a sequence.
Using Where method to filter
The Where
method can be used to filter a sequence based on the predicate. A predicate is expressed using lambda expression and predicates return boolean values - true
or false
.
To filter all automatic cars from the Cars
sequence.
IEnumerableAutomaticCars = Cars.Where(car => car.Transmission == "Automatic");
The predicate in the above code is
car => car.Transmission == "Automatic"
This LINQ query returns the following cars
Mercedes-Benz-E Class Audi-Q7 Toyota-Auris
The Where
method also allows you to use each elements index in the predicate. For example, the below code get all cars with automatic transmission and index position not equal to 1.
IEnumerableAutomaticCars = Cars.Where((car,index) => car.Transmission == "Automatic" && index != 1);
This will filter out Mercedes-Benz from the result as it is index position 1 on the collection.
Audi-Q7 Toyota-Auris
The following table lists commonly used LINQ methods with example usage on the Cars sequence.
Method | Description & Usage | |
---|---|---|
Selecting | ||
ElementAt | Returns the element at the specified index position in the sequence. Index is zero-based so index of the first element is 0. Car c = Cars.ElementAt(2); /* Returns Audi */ | |
First | Returns the first element of a sequence. Car firstCar = Cars.First(); /* Returns BMW */ | |
Returns the first element that match the specified condion in the sequence. Car firstCar = Cars.First(c => c.Transmission == "Automatic"); /* Returns Mercedes-Benz */ | ||
Last | Returns the last element of a sequence. Car lastCar = Cars.Last(); /* Returns Ford */ | |
Returns the last element that match the specified condion in the sequence. Car lastCar = Cars.Last(c => c.Transmission == "Automatic"); /* Returns Toyota */ | ||
Select | Transforms each object in the sequence to a different form. In the following example the Make and Model of each car is combined to return a new list of strings. IEnumerable<string> CarMakeModel = Cars.Select(car => car.Make + " " + car.Model); /* Returns a list containing the following strings. BMW 3 Series Mercedes - Benz E Class Audi Q7 Toyota Auris Ford Focus */ | |
Single | This method call returns a single element in the sequence that satisfies the specified condition. An error is thrown if there are more than one element that maches the condition. Car HybridCar = Cars.Single( c => c.FuelType == "Hybrid"); | |
Take | Returns the first N number of elements from the sequence where N is a positive integer. IEnumerable<Car> FirstTwo = Cars.Take(2); | |
TakeLast | Returns the last N number of elements from the sequence where N is a positive integer. IEnumerable<Car> LastTwo = Cars.TakeLast(2); | |
TakeWhile | Returns elements from the starting of the sequence while the condition is IEnumerable<Car> query = Cars.TakeWhile(c => c.FuelType != "Diesel"); /* Returns BMW and Mercedes-Benz */ You could also use the index of the element in the condition. The following example return first 3 elements. IEnumerable<Car> query = Cars.TakeWhile((c,index) => index != 3); | |
Checking | ||
Any | Check if any element exist in the sequence. bool check = Cars.Any(); /* Returns: True */ | |
Check if an element that matches the specified condition exist in the sequence. bool check = Cars.Any(c => c.FuelType == "Hybrid"); /* Returns: True */ | ||
All | Check if the specified condition holds true for all elements in the sequence. bool AllPetrolCars = Cars.All(c => c.FuelType == "Petrol"); /* Returns: False */ | |
Methods for Aggregate functions | ||
Count | If no argument is specificed, int count = Cars.Count(); /* count = 5 */ int countManual = Cars.Count(c => c.Transmission == "Manual"); /* count = 2 */ | |
Max | Returns the maximum value in a sequence.int maxYear = Cars.Max(c => c.Year); /* returns 2020 */ | |
Min | Returns the minimum value in a sequence.int maxYear = Cars.Min(c => c.Year); /* returns 2013 */ | |
Conversion | ||
ToDictionary | Converts the IEnumberable collection to a dictionary (key-value pairs). Dictionary You will get a duplicate key error if the key is not unique in the collection. | |
ToList | Converts the IEnumberable collection to a List. List |