DEV Community

Rasheed K Mozaffar
Rasheed K Mozaffar

Posted on

4

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.

//2
int first = numbersArray.First();

//-120
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;

//OUPUT : TONY , BRO
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 ! :)

Image of Timescale

🚀 pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applications—without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read more →

Top comments (0)

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more