Introduction
Every language has features that attract users. C# has one of its powerful features known as Language Integrated Query or LINQ. It adds enormous power to the .NET framework with its libraries. LINQ helps you to write simple yet powerful code that is faster and less error prone and easy to understand and debug.
The objective of this article is to provide the beginners to show what benefit LINQ provides. Hopefully one will be able to learn and will be able to use it at the end.
Components
LINQ has several components:
- Providers: Libraries that enable querying various types of collections (LINQ to XML, LINQ to Objects, LINQ to SQL and so on)
- Language Extensions: Several features added to the framework to support LINQ (Anonymous methods, Lambda expressions, Anonymous types, Extension methods and so on)
- Operations: Various query operation supports like Select(). [Common query names]
A Key to Understand
It's very important to understand the “Iterator” concept to be a LINQ expert. It gives LINQ a lot of power to create queries with deferred execution. This means it provides a way for you to be able to return a sequence of objects one item at a time, as they are requested.
Let's say we have a List of Employees and we want to find all the employees whose salary is equal or greater than 10000. Let's see the first example:
- public static List<Employee> GetHighPaidEmployees(List<Employee> source)
- {
- var res = new List<Employee>();
- foreach (var emp in source)
- {
- if (emp.Salary >= 10000)
- res.Add(emp);
- }
- return res;
- }
This works fine. But what if we want to get only the first 5 employees from the high paid list? That's where iterators are useful. Let's modify the preceding function as in:
- public static IEnumerable<Employee> GetHighPaidEmployee(List<Employee> source)
- {
- foreach (var emp in source)
- {
- if (emp.Salary >= 10000)
- yield return emp;
- }
- }
See, we didn't create any container to hold the filtered list, instead we used a “yield return” statement to get the result. That means the query or filter will not be executed unless we request it. Let's see what the difference is from this small code snippet:
- var empList = new List<Employee> { new Employee() { Name = "Arunava", Salary = 5000 }, new Employee() { Name = "Bubu", Salary = 10000 } };
-
- var highEmpList = GetHighPaidEmployee(empList);
- empList.Clear();
-
- Console.WriteLine(highEmpList.Count());
- Console.ReadLine();
The output will be 0 since the original list is cleared before the query executed. This is known as deferred execution and it is a forefront of LINQ.
Lambda and Query Expressions
These two are very important components of LINQ. Lambda expressions make it easy to write short, anonymous methods at the point where they are used. Lambda expressions just took the anonymous method syntax and simplified it even further:
- Func<Employee, bool> res = delegate(Employee emp) { return emp.Salary > 1000; };
- Console.WriteLine(empList.Count(res));
Finding it difficult to understand the upper code? Well it just used a func delegate and anonymous method to get all the employees whose salary is greater than 1000. The same operation can also be done using a Lambda Expression as:
- Console.WriteLine(empList.Count(e=>e.Salary>1000));
It is very readable and one can easily understand. Also, it reduced code space and development time. Easy to design and easy to maintain.
There is another feature called Query Expressions that provide the query operations a more SQL-ish feel to make querying objects seem more natural. Using the query expression you can remove all the methods we wrote in the beginning of this article and can just write only this piece of code:
- var qe = from e in empList
- where e.Salary > 10000
- select e;
People with just a basic idea of SQL can easily understand this code. But please do remember it is a deferred query. It internally uses the “yield” mechanism as discussed previously.
Conclusion:With this short article I hope you can now start with any LINQ tutorial and write your own query expressions or lambda. Personally, I use query expression for Group By, Joins and Order By. Other places lambdas are sufficient. I hope this helps.