Hi Friends,
In today’s discussion, we’ll look into LINQ operations. LINQ or Language Integrated Query is a set of language and framework features for constructing type safe queries over local collections or remote data sources. It was introduced in C# 3.0 and framework 3.5.
The basic units of data in LINQ are sequence of elements which actually implements IEnumerable
employees is sequence and “John”,”Dave”,”Black”,”Jack” are elements.
string[] employees = {"John","Dave","Black","Jack"};
A query operator is the one which transforms the sequence. A typical query operator accepts a sequence and emits a transformed output sequence. For, IEnumerable case, we have around 40 query operators. They are also known standard operators.
Let us get started with few simple queries.
Note:- I am using LINQPAD to run these queries. Hence, final statement dump is specific to it. It’s basically used to show the output.
string[] employees = {"John","Dave","Black","Jack","Rahul"}; IEnumerable<string> filtered_emp = employees.Where(n=>n.Length>4); filtered_emp.Dump("Simple usage of Query");
Since, standard query operators are implemented as static methods, we can directly call Where on employees. Most query operators accept lambda expressions as an argument like here we have n=>n.Length>4.
Now, Let’s look at complex query
string[] employees = {"John","Dave","Black","Jack","Rahul"}; IEnumerable<string> query = employees.Where(n=>n.Contains("a")) .OrderBy(n=>n.Length) .Select(n=>n.ToLower()); query.Dump("Simple usage of Query");
here, what it is doing; taking the input, extracts all the strings containing letter a then sorts them by length and then converts the same in lower case. Here, the variable n is privately scoped to each lambda expressions. Here, OrderBy and Select are standard query Operators.
Now, let’s look at Range Variable. The Identifier immediately following the from keyword syntax is called the Range variable. For instance, in below example
from n in new[] { "John","Dave","Black","Jack","Rahul" } where n.Contains ("a") select n
Chaining of query operator is very efficient in many cases like shown below.
string[] names = { "John","Dave","Black","Jack","Rahul" }; IEnumerable<string> query = names .Where (n => n.Contains ("a")) .OrderBy (n => n.Length) .Select (n => n.ToUpper()); query.Dump(); // same query rewritten progressively: IEnumerable<string> filtered = names.Where (n => n.Contains ("a")); IEnumerable<string> sorted = filtered.OrderBy (n => n.Length); IEnumerable<string> finalone = sorted.Select (n => n.ToUpper()); filtered.Dump ("Filtered"); sorted.Dump ("Sorted"); finalone.Dump ("FinalQuery");
So, as you can see in the above example same final query is achieved in the first expression and again same thing achieved differently by writing the same progressively. Similarly, sometimes we need to keep the natural ordering of numbers as it is.
int[] numbers = { 10, 9, 8, 7, 6 }; numbers.Take (3) .Dump ("Take(3) returns the first three numbers in the sequence"); numbers.Skip (3) .Dump ("Skip(3) returns all but the first three numbers in the sequence"); numbers.Reverse() .Dump ("Reverse does exactly as it says");
Now, in the end there are other important operators which are equally important.
int[] numbers = { 10, 9, 8, 7, 6 }; // Element operators: numbers.First().Dump ("First"); numbers.Last().Dump ("Last"); numbers.ElementAt (1).Dump ("Second number"); numbers.OrderBy (n => n).First().Dump ("Lowest number"); numbers.OrderBy (n => n).Skip(1).First().Dump ("Second lowest number"); // Aggregation operators: numbers.Count().Dump ("Count"); numbers.Min().Dump ("Min"); // Quantifiers: numbers.Contains (9).Dump ("Contains (9)"); numbers.Any().Dump ("Any"); numbers.Any (n => n % 2 != 0).Dump ("Has an odd numbered element"); // Set based operators: int[] seq1 = { 1, 2, 3 }; int[] seq2 = { 3, 4, 5 }; seq1.Concat (seq2).Dump ("Concat"); seq1.Union (seq2).Dump ("Union");
Thanks for Joining me.
Thanks,
Rahul Sahay
Happy Coding
Thank you!
SergeChel recently posted…Xandria – Nightfall