LINQ (Language Integrated Query) – Part 1

Language Integrated Query (LINQ) was basically introduced on C# 3.0 & .NET framework 3.5.

The idea behind this was, suppose someday we are working on SQL server database, so we need to learn SQL server syntax, SQL related ADO.NET objects. Now suppose after some time we switched to an Oracle database, so again we need to grab command on oracle related syntax & oracle related ADO.NET objects to work with C#.

So basically, this problem arises with the number of technologies we adapt, we need to learn all of them. In order to avoid this, Microsoft introduced LINQ, where we cannot only work with collections populated from the database but with various other data sources as well as an XML file, an in-memory datatable etc. We can even use LINQ when working with Reflections. In .Net any data source which implements IEnumerable interface can be used for querying, filtering, grouping, ordering & projecting data.

What is LINQ?

The full form of LINQ is Language Integrated Query. This provides us to run query for any type of data store like SQL Server, XML documents, Objects in memory etc.

LINQ: Benefits And Its Need

Benefits

  • LINQ provides us with the common syntax for querying any type of data sources.
  • LINQ  binds the gap between relational and object-oriented approaches.
  • LINQ expedites development time by catching errors at compile time and includes IntelliSense & Debugging support.
  • LINQ expressions are Strongly Typed.

Another benefit of using LINQ is that it provides intelligence and compile time error checking.

LINQ Architecture & LINQ Providers

  1. LINQ query can be written in any .NET supported programming language.
  2. LINQ provider works as a glue between the LINQ query and the data source, that helps to converts the LINQ query into a format that the underlying data source can understand. Let’s have an example LINQ to SQL provider converts a LINQ query to T-SQL that SQL Server database can understand.

LINQ Queries

To write LINQ queries we follow the LINQ Standard Query Operators. The following are several Examples of Standard Query Operators:
1.select
2.from
3.where
4.orderby
5.join
6.groupby  etc.

Example :-

We will use the following Employee class in this demo. GetAllEmployees() is a static method that returns List. Since List implements the  IEnumerable interface and  the LINQ Query Operators will be available and can be applied on List.

public class Employee

{

public int ID { get; set; }

public string Name { get; set; }

public string Gender { get; set; }

public static List<Employee> GetAllEmployees()

{

List<Employee> listEmployees = new List<Employee>();

Employee employee1 = new Employee

{

ID = 101,

Name = "Mark",

Gender = "Male"

};

listEmployees .Add(employee1);

Employee employee2= new Employee

{

ID = 102,

Name = "Mary",

Gender = "Female"

};

listEmployees.Add(employee2);

Employee employee3 = new Employee

{

ID = 103,

Name = "John",

Gender = "Male"

};

listEmployees.Add(employee3);

return listEmployees;

     }

}

As per the below LINQ query, it should return All the Male Employee.

  • LINQ query using Lambda Expressions.
    • IEnumerable<Employee> employee = Student.GetAllEmployees() Where(employee => employee.Gender == “Male”);
  • LINQ query using using SQL like query expressions
    • IEnumerable<Employee> employee = from employee in employee.GetAllemployees() where employee.Gender == “Male”   select employ

Extension Methods

Extension methods allow us to add methods to existing types without creating a new derived type.
Extension methods are the special kind of static method, but they are called as if they were instance methods on the extended type.

Let’s understand what the actual meaning of this…
LINQ’s standard query operators (select, where, groupby etc ) are implemented in Enumerable class as extension methods on the IEnumerable<T> interface.

Now look at the following query:

List<int> AllNumbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

 

IEnumerable<int> EvenNumbers = AllNumbers .Where(n => n % 2 == 0);

In spite of Where() method not belonging to List<T> class, we are still able to use it as though it belong to List<T> class. This is possible because here  Where method is implemented as extension method in IEnumerable<T> interface and List<T> implements IEnumerable<T> interface.

How can we implement extension methods?

We want to define a method in the string class called it ChangedFirstLetterCase, which will change the case of the first letter of the string. For example, if the first letter of the string is lowercase the function should change it to uppercase and if the first letter of the string is uppercase the function should change it to lowercase.

We want to be able to call this function on the string object as shown below.

string result = strName.ConvertFirstLetter();

Defining ConvertFirstLetter() method directly in the string class is not possible as we do not  own the string class. It belongs to .NET framework. Another alternative is to write a wrapper class as shown below.

public class StringHelper

{

public static string ConvertFirstLetter(string inputString)

{

if (inputString.Length > 0)

{

char[] charArray = inputString.ToCharArray();

charArray[0] = char.IsUpper(charArray[0]) ?

char.ToLower(charArray[0]) : char.ToUpper(charArray[0]);

return new string(charArray);

}

return inputString;

}

}

we cannot call ConvertFirstLetter() method using the below syntax:-
string resultview= stringName.ConvertFirstLetter();

Apart from that, we have to call it as shown below.
string resultview= StringHelper.ConvertFirstLetter(stringName);

Convert ConvertFirstLetter() method to an extension method to be able to call it using the following syntax, as though it belongs to string class.
string resultview= stringName.ConvertFirstLetter();

With these changes, we are able to call this extension method in the same way we call an instance method. Here an important thing to focus on that the extension method shows up in the intellisense as well, but with a different visual clue.
string result = stringName.ConvertFirstLetter();

Please note that, if our extension method has a parameter, then the parameter should be the second parameter when we call the extension method because of the first parameter always a class name with this keyword.

Please note , we should still be able to call this extension method using wrapper class style syntax. In fact,  how the extension method actually gets called.
string result = StringHelper.ConvertFirstLetter(strName);

So, this means we also be able to call LINQ extension methods (select, where etc), using wrapper class style syntax. Since all LINQ extension methods are defined in the Enumerable class, the syntax will be as shown below.

List<int> AllNumbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

IEnumerable<int> EvenNumbers = Enumerable.Where(AllNumbers , n => n % 2 == 0);

Advantages of extension methods

  1. Extend the functionality of libraries you do not have access to the code – Suppose you have a third-party library and you would like it to add more methods without recompiling the original code, you will take the advantage of extension methods and add the functionality by yourself only. Your development team will use them as if they were shipped to the original library.
  2. Cleaner and simpler syntax – All we have to do are write variable name then dot and the extension method name and you are done.
  3. Code readability – As Per above example, use of extension methods results in few lines of code written. This greatly improves the code readability
  4. Discoverability – Variable name plus dot will give you the all method name by intellisense, this serves you time when coding.

CONCLUSION

After all the above explanation, I hope now you are quite clear about the things. Although for any further queries, you are free to post your valuable comments in the comments section below!

Leave a Comment