What is LINQ? The .NET Language Integrated Query

LINQ is built into the .NET framework and allows you to easily query and manipulate data across sources in a consistent manner.

By Tim TrottIntroduction to Programming with C# • September 8, 2008
1,023 words, estimated reading time 4 minutes.
Introduction to Programming with C#

This article is part of a series of articles. Please use the links below to navigate between the articles.

  1. Learn to Program in C# - Full Introduction to Programming Course
  2. Introdution to Programming - C# Programming Fundamentals
  3. Guide to C# Data Types, Variables and Object Casting
  4. C# Operators: Arithmetic, Comparison, Logical and more
  5. Application Flow Control and Control Structures in C#
  6. Introduction to Object Oriented Programming for Beginners
  7. Introduction to C# Object-Oriented Programming Part 2
  8. C# Collection Types (Array,List,Dictionary,HashTable and More)
  9. Error and Exception Handling in C#
  10. Events, Delegates and Extension Methods
  11. Complete Guide to File Handling in C# - Reading and Writing Files
  12. Introduction to XML and XmlDocument with C#
  13. What is LINQ? The .NET Language Integrated Query
  14. Introduction to Asynchronous Programming in C#
  15. Working with Databases using Entity Framework
  16. All About Reflection in C# To Read Metadata and Find Assemblies
  17. Debugging and Testing in C#
  18. Introduction to ASP.Net MVC Web Applications and C#
  19. Windows Application Development Using .Net and Windows Forms
  20. Assemblies and the Global Assembly Cache in C#
  21. Working with Resources Files, Culture & Regions in .Net
  22. The Ultimate Guide to Regular Expressions: Everything You Need to Know
What is LINQ? The .NET Language Integrated Query

LINQ (Language-Integrated Query) is a technology built into the .NET framework that will allow you to query and consistently easily and manipulate data across various sources. It doesn't matter if the data is an array or a database; the methods and syntax are the same.

LINQ is extremely powerful for working with data, and you can do many things by simply chaining commands along one line.

In this example, we can select from an array all the names with eight or fewer characters in length and order them alphabetically.

C#
var names = new List<string>()  
{  
    "Kealan Pemberton",  
    "Kurtis Hayward",  
    "Hilary Bray",  
    "Nylah Fitzpatrick",
    "Brandon Hendrix",
    "Najma Pike",
    "Milosz Hester",
    "Ayda Reilly"
};  

var filteredNames = from name in names where name.Length <= 12 orderby name.Length select name;

foreach (var name in filteredNames)  
    Console.WriteLine(name);

LINQ Query Syntax vs. Method Syntax

LINQ statements can be written in one of two ways. The first query syntax we have seen above is similar to the syntax used in SQL. The second method is more procedural, using methods to represent query functions. Here are two examples of the different syntaxes.

LINQ Query Suntax

C#
var lastNames = from person in persons
where person.Age > 12
orderby person.LastName
select person.LastName;

LINQ Method Syntax

C#
var lastName = persons
  .Where(person => person.Age > 12)
  .OrderBy(person => person.LastName)
  .Select(person => person.LastName);

The person is declared once in the query syntax and used in the where, orderby, and select clauses. Using the method syntax, you have to redeclare the person each time in the lambda expressions.

The compiler processes the query; there isn't any performance difference, so the choice of which to use is up to the developer.

I prefer method syntax; it is good for generating LINQ queries dynamically with expression trees and such. Query syntax is better for complicated queries with many lets, joins, and nested projections.

I'll use method syntax for most of the tutorials on this site.

Filtering Data with LINQ

One of the most basic operations you can perform on a data set is to filter some of it out.

C#
var names = new List<string>()  
{  
    "Kealan Pemberton",  
    "Kurtis Hayward",  
    "Hilary Bray",  
    "Nylah Fitzpatrick",
    "Brandon Hendrix",
    "Najma Pike",
    "Milosz Hester",
    "Ayda Reilly"
};  

var filteredNames = names.Where(x => x.Length <= 12)

foreach (var name in filteredNames)  
    Console.WriteLine(name);

This filters out everything where the length is greater than 12.

We can add multiple conditions to the where clause to filter the results further.

C#
var filteredNames = names.Where(x => x.Length <= 12 &amp;&amp; x.Length > 5)

We can also filter results to check whether a value is contained or not within another predefined list of values.

C#
var numbers = new List<int>()
{
    1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377
};

var excludedNumbers = new List<int>()
{
    21, 89
};

var validNumbers = numbers.Where(n => !excludedNumbers.Contains(n));

foreach (var n in validNumbers)
    Console.WriteLine(n);

Sorting Data with LINQ

Another powerful and hugely useful method LINQ provides is data sorting. We can use OrderBy and OrderByDescending to sort our data.

C#
var unorderedNumbers = new List<int>()
{
    1, 13, 144, 2, 21, 233, 3, 34, 377, 5, 55, 8, 89
};

var orderedNumbers = unorderedNumbers.OrderBy(x => x);

We can perform operations on complex objects as well.

C#
class person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

var persons = new List<person>()
{
    new person()
    {
        Name = "Kealan Pemberton",
        Age = 55
    },
    new person()
    {
        Name = "Kurtis Hayward",
        Age = 21
    },
    new person()
    {
        Name = "Hilary Bray",
        Age = 34
    }
};

var sortedPersons = persons.OrderBy(x => x.Age);

Limiting Data with LINQ

Now we have filtered and sorted the data, we can limit the number of records. This is especially useful when using a database as a data source because it often involves huge amounts of rows, which are resource-consuming to fetch.

The methods for limiting records are called Take() and Skip(), and in combination, they are great for doing pagination on a website.

Take specifies the number of records to return, and Skip specifies the number of results to skip before taking the records.

C#
var names = new List<string>()  
{  
    "Kealan Pemberton",  
    "Kurtis Hayward",  
    "Hilary Bray",  
    "Nylah Fitzpatrick",
    "Brandon Hendrix",
    "Najma Pike",
    "Milosz Hester",
    "Ayda Reilly"
};  

var names = names.Skip(1).Take(2).ToList();

You often have a page size and a current page number for pagination.

C#
var names = new List<string>()
{
    "Kealan Pemberton",
    "Kurtis Hayward",
    "Hilary Bray",
    "Nylah Fitzpatrick",
    "Brandon Hendrix",
    "Najma Pike",
    "Milosz Hester",
    "Ayda Reilly"
};

var pageSize = 5;
var currentPage = 1;
var results = names.Skip(pageSize * currentPage).Take(pageSize);

Data Transformations with LINQ

Finally, we can transform the original data types to another type as part of the query. We can do this using the Select method. Consider the person's class previously, and suppose we want a list of names. We can select just the name part to return a list of strings.

C#
class person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

var persons = new List<person>()
{
    new person()
    {
        Name = "Kealan Pemberton",
        Age = 55
    },
    new person()
    {
        Name = "Kurtis Hayward",
        Age = 21
    },
    new person()
    {
        Name = "Hilary Bray",
        Age = 34
    }
};

List<string> namesOnly = persons.Select(x => x.Name).ToList();

Grouping Results with LINQ

When you group data, you take a list of something and divide it into several groups based on one or several properties. With LINQ, this is very easy, even though using the GroupBy() method can be confusing initially.

C#
var persons = new List<person>()
{
    new person()
    {
        Name = "Kealan Pemberton",
        Age = 55,
        Country = "GB"
    },
    new person()
    {
        Name = "Kurtis Hayward",
        Age = 21,
        Country = "GB"
    },
    new person()
    {
        Name = "Hilary Bray",
        Age = 34,
        Country = "US"
    }
};

var nameGroupedByCountry = persons.GroupBy(user => user.Country);
foreach (var group in nameGroupedByCountry)
{
    Console.WriteLine("People from " + group.Key + ":");
    foreach (var person in group)
        Console.WriteLine("- " + person.Name);
}

Chaining LINQ Queries

Now that we have seen the different methods, we can combine them to sort, filter, page, and select results in a single query.

C#
var persons = new List<person>()
{
    new person()
    {
        Name = "Kealan Pemberton",
        Age = 55,
        Country = "GB"
    },
    new person()
    {
        Name = "Kurtis Hayward",
        Age = 21,
        Country = "GB"
    },
    new person()
    {
        Name = "Hilary Bray",
        Age = 34,
        Country = "US"
    }
};

List<string> namesOnly = persons.Where(x => x.Name.Length >= 12).OrderBy(x => x.Name).Take(3).Skip(5).Select(x => x.Name).ToList();

About the Author

Tim Trott is a senior software engineer with over 20 years of experience in designing, building, and maintaining software systems across a range of industries. Passionate about clean code, scalable architecture, and continuous learning, he specialises in creating robust solutions that solve real-world problems. He is currently based in Edinburgh, where he develops innovative software and collaborates with teams around the globe.

Related ArticlesThese articles may also be of interest to you

CommentsShare your thoughts in the comments below

My website and its content are free to use without the clutter of adverts, popups, marketing messages or anything else like that. If you enjoyed reading this article, or it helped you in some way, all I ask in return is you leave a comment below or share this page with your friends. Thank you.

There are no comments yet. Why not get the discussion started?

New comments for this post are currently closed.