DEV Community

Rasheed K Mozaffar
Rasheed K Mozaffar

Posted on


Basics Of LINQ In C# With Examples

Language INtegrated Query or LINQ for short , is a very powerful feature in C# , which can be used to retrieve and query various kinds of collections and data sources.

Traditionally , queries against data is mostly done through strings without type checking at compile time or IntelliSense support , which makes it difficult to write queries especially large queries that involve various conditions within a single query, additionally , you need to learn a different query language for the various data sources , like SQL databases and XML documents , which is somewhat cumbersome.

So fortunately, LINQ comes for the rescue.
LINQ provides a couple of ways to write queries

1: Query expressions which are written in a declarative query syntax similar to SQL .
2: Extension methods with Lambda expressions.

And to explain the variety of features LINQ provides , we will use examples using both the query expressions syntax and extension methods.

For that purpose , we will use a simple console application for the sake of simplicity , but keep in mind that all the examples mentioned below are viable and applicable in all use cases no matter what the project type is.

Ok , so create a C# console app , and make sure to use top-level statements so your codes looks a bit cleaner without all the boilerplate code.

Let's declare a basic array of integers first...
int[] numbersArray = {2 , -1 , 10 , 99 , 78 , -21 , 45 , 0 , -120};

Ok , this simple array will be our data source for now.
We will write a simple query to get all the negative numbers , the implementation goes as follows

var negativeNumbers = from number in numbersArray
                      where number < 0
                      select number;
Enter fullscreen mode Exit fullscreen mode

We can use the var keyword to let the compiler infer the type of this variable , which is called a query variable in this case , this variable actually stores the query and not the collection of the negative numbers , the query will be converted only when executed , so , we will use a foreach loop for that

foreach(int number in negativeNumbers)
    Console.Write($"{number} ");
    //OUTPUT : -1 , -21 , -120
Enter fullscreen mode Exit fullscreen mode

This way , we used the query expression syntax , let's see how we can do it with the extension methods way

var negativeNumbers = numbersArray.Where(x => x < 0);
This one line basically does the same thing as the previous query , this line reads like this : from the numbers array , select all the numbers that are less than 0 .

Let's try something new , we will now get both the first and last elements in the array , we'll do it with the extension methods cause it's pretty easy.

int first = numbersArray.First();

int last = numbersArray.Last();
Enter fullscreen mode Exit fullscreen mode

If you are using Visual Studio , you might notice things like FirstOrDefault() & LastOrDefault() , these are similar to First() & Last() except , when an element is not found in the sequence , they return the default value , 0 for value types and null for reference types.

Ok , now we'll check if a data source is empty or not , to do that , again , it's fairly simple , all we gotta do is call the Any() extension method on the data source , if it's empty , it'll return false , if not , then it'll return true.

bool anythingThere = numbersArray.Any();
//OUTPUT: true
Enter fullscreen mode Exit fullscreen mode

Our data source has values in it , so this line will return true.

Now , we will ramp up the game a bit , we will declare an employee class , and then initialize a generic list with some dummy values as our data source.
Create a new class named Employee

public class Employee
    public string FirstName {get; set;}
    public string LastName {get; set;}
    public decimal Salary {get; set;}
Enter fullscreen mode Exit fullscreen mode

This should do , we are trying to keep it as simple as possible here.
I'll create a List of the Employee type we just introduced and use some dummy names and values just for the purpose of our queries.

List<Employee> employees = new()
    new Employee {FirstName = "Tony" , LastName = "Dude" , Salary = 100_000 },
    new Employee {FirstName = "Bro" , LastName = "Space" , Salary = 80_000},
    new Employee {FirstName = "Jeff" , LastName = "Stanley" , Salary = 122_020},
    new Employee {FirstName = "Rick" , LastName = "Stark" , Salary = 12_099},
    new Employee {FirstName = "Alex" , LastName = "Peters" , Salary = 7_400},
    new Employee {FirstName = "Tracey" , LastName = "Peters" , Salary = 217_400}
Enter fullscreen mode Exit fullscreen mode

I Truly apologize for the horrible names , but they'll do for now.
With that out of the way , let's query the new data source to get the first names that contain the letter O.

Query Expressions

var containsO = from employee in employees
                where employee.FirstName.ToLower().Contains('o')
                select employee;

Enter fullscreen mode Exit fullscreen mode

The cool thing about query expressions is that they read almost like normal english , so query reads like this :

for each employee in the employees collection , select all employees whose first name contains the letter o after converting the first name to lower case.

Ok , we've talked enough about retrieving data and stuff , how about some math operations that LINQ provides for us , let's apply some of them now.

Finding the SUM of all the employees' salaries , let's code it

decimal salariesSum = employees.Sum(e => e.Salary); //OUTPUT : 538919

This one line calculates the sum of all the salaries , and it returns a decimal cause the Salary property is of type decimal which makes perfect sense.

Finding the AVERAGE of the salaries of our imaginary employees , again , with LINQ , it's pretty simple , let's see it in action
decimal averageSalary = employees.Average(e => e.Salary); //OUTPUT : 89819.833....

Finding the MAXIMUM salary in our collection
decimal max = employees.Max(e => e.Salary); //OUTPUT : 217400

Finding the MINIMUM salary in our collection , similar to the maximum , we just replace Max() with Min()
decimal min = employees.Min(e => e.Salary);

OK !

We've covered some of the basic things that LINQ can provide for you as a C# developer , as you can tell , there are plenty of productive functionality that LINQ brings to the table , and just for reference , we applied these functions on basic data sources like an array of numbers and a basic generic list , but LINQ works with all sorts of data sources , like the DB SETS in Entity Framework Core so you can query data from your database tables effectively through LINQ.

Finally , a small explanation of how a query expression is structured
A query expression always MUST start with the keyword from x in data source , then we can stack up some conditions , and then the final line MUST end with select or group.

I hope you found that useful and was worth your time , but obviously , there's still so much to learn in LINQ beyond the basics of today , so if you wanna continue digging deeper in LINQ , make sure to check out Microsoft Docs for extra help and to further deepen your knowledge of the technology.

Thanks For Reading ! :)

Top comments (0)