LINQ in C# Explained In Five Minutes

Petey
Petey
Jan 10 · 5 min read
Photo by National Cancer Institute on Unsplash

In most cases, regardless of which tech stack you use, you’ll have some kind of backend service to retrieve data when designing an application. The data can come from different sources. Each data source might have a specific language. If you have an application that retrieves data from four different sources, you’d have to learn all four languages to query the data. This is where LINQ comes to the rescue.


LINQ simplifies this situation by offering a consistent model for working with data across various kinds of data sources and formats. If you are familiar with SQL then this will seem very familiar. Some basic C# knowledge, version 7.0 and above, is required to follow along. I am to use Visual Studio on a mac. It can be downloaded for windows and mac here.

Open visual studio, and select Console Project as your template, then name your project linqDemo. For brevity, I’ve written a Car class with a constructor and a static method that returns a collection of cars, which we will use as our data source. I’m going to cover some of the most common features, such as SELECT, WHERE, ORDERBY and GROUPBY.

Replace your entire Program.cs file with this code.

using System;
using System.Collections.Generic;
using System.Linq;
namespace linqDemo
{
class MainClass
{
public static void Main(string[] args)
{
}
}
class Car
{
public string Make { get; set; }
public string Model { get; set; }
public int Year { get; set; }
public int availQty { get; set; }
public double MSRP { get; set; }
public Car(string make, string model, int year, int availQty, double msrp)
{
this.Make = make;
this.Model = model;
this.Year = year;
this.availQty = availQty;
this.MSRP = msrp;
}
public static List<Car> getInventory()
{
return new List<Car>
{
new Car("BMW", "X5",2019,34,61000),
new Car("BMW", "328", 2018, 84,37000),
new Car("BMW", "x3", 2020, 242, 41000),
new Car ("Ford", "F-150", 2012,33, 28155),
new Car("Audi", "Q3", 2018,42,41000),
new Car("Audi", "Q5", 2020, 121, 43300),
new Car("Acura", "RDX", 2019, 222,37400),
new Car("Lexus", "RX 350", 2019, 23, 44150),
new Car("Mercedes Benz", "C300", 2019,232, 40250)
};
}
}
}

A query LINQ query is comprised of three parts. A data source, which in our case will be provided via the static method, is a query and the execution of the query.

Let’s get started. We’re going to write our first link query. We will select all the cars in our inventory. The count should be three. Here’s the code for the query.

//data source is Car.getInventory()//query
var query = from car in Car.getInventory()
select car;

LINQ defers query execution until you iterate over the collection. That means this query does nothing until you use it. But you can force the executive by using one of the aggregate functions. We’ll use a few of them later on. So let’s use it to print the count of all cars.

//getting and print count of all cars
var count = query.ToList().Count;
Console.WriteLine($"Total count is {count}");

The inside of your Main method should look like this now.

//data source is Car.getInventory()//query
var query = from car in Car.getInventory()
select car;
//getting and print count of all cars
var count = query.ToList().Count;
Console.WriteLine($"Total count is {count}");

Run the code to see the out.

The SELECT keyword will be present in every LINQ query you write.

“Where” is used to filter data given specific criteria. If I wanted to only get all BMW cars, then I’d add a where to the query.

//bmw cars
var bmwCars = from car in Car.getInventory()
where car.Make == "BMW"
select car;
Console.WriteLine($"Total nBMW car count is {bmwCars.ToList().Count}");//out

Multiple filters can also be applied with the where clause. Let’s select all cars built in the year 2019 and make is not BMW

var nonBMWCars = from car in Car.getInventory()
where car.Make != "BMW"
where car.Year == 2019
select car;
Console.WriteLine($"Total non-BMW car count is {nonBMWCars.ToList().Count}");

Orderby is used to order the returned sequence by any accessible field. A query can be ordered by ascending or descending order. The query below orders the result by “make” in descending order.

var orderdByMakeCars = from car in Car.getInventory()
orderby car.Make descending
select car;

I overrode the ToString method in the Car class. Add this line of code right above the static getInventory method.

public override string ToString() => $"Make:{Make} Model:{Model} Year:{Year} AvailQty:{availQty} MSRP:{MSRP}";

Now we can iterate the collection to make sure we got back the result expected result.

//print result ordered by make in descending order
orderdByMakeCars.ToList().ForEach(car =>
{
Console.WriteLine(car);
});
Make:Mercedes Benz Model:C300 Year:2019 AvailQty:232 MSRP:40250
Make:Lexus Model:RX 350 Year:2019 AvailQty:23 MSRP:44150
Make:Ford Model:F-150 Year:2012 AvailQty:33 MSRP:28155
Make:BMW Model:X5 Year:2019 AvailQty:34 MSRP:61000
Make:BMW Model:328 Year:2018 AvailQty:84 MSRP:37000
Make:BMW Model:x3 Year:2020 AvailQty:242 MSRP:41000
Make:Audi Model:Q3 Year:2018 AvailQty:42 MSRP:41000
Make:Audi Model:Q5 Year:2020 AvailQty:121 MSRP:43300
Make:Acura Model:RDX Year:2019 AvailQty:222 MSRP:37400

Grouping is one of my favorite LINQ features and is a powerful capability in query expressions. A query with a group clause produces a sequence of groups, and each group itself contains a Key and a sequence that consists of all the members of that group. The resulted set is filtered ascendingly by default unless specified in the query. The query below group cars by year.

//group cars by year
var groupedByYearCars = from car in Car.getInventory()
group car by car.Year;

Iterate through the result is easy.

//iterate through collection
groupedByYearCars.ToList().ForEach(group =>
{
Console.WriteLine(group.Key);
group.ToList().ForEach(car =>
{
Console.WriteLine(car);
});
});
/*
2019
Make:BMW Model:X5 Year:2019 AvailQty:34 MSRP:61000
Make:Acura Model:RDX Year:2019 AvailQty:222 MSRP:37400
Make:Lexus Model:RX 350 Year:2019 AvailQty:23 MSRP:44150
Make:Mercedes Benz Model:C300 Year:2019 AvailQty:232 MSRP:40250
2018
Make:BMW Model:328 Year:2018 AvailQty:84 MSRP:37000
Make:Audi Model:Q3 Year:2018 AvailQty:42 MSRP:41000
2020
Make:BMW Model:x3 Year:2020 AvailQty:242 MSRP:41000
Make:Audi Model:Q5 Year:2020 AvailQty:121 MSRP:43300
2012
Make:Ford Model:F-150 Year:2012 AvailQty:33 MSRP:28155
*/

Join is a very nice feature. It allows joining tables on a primary or foreign key. I’ve created a new class named CarPromo. This class contains two properties. Make and Slogan. I’ve also created a method called getPromo that returns a collection of CarPromo. We’re going to join the data from the getInventory with the data from getPromo method call to print the make, model and slogan.

Add this code right before your Car class to create the CarPromo class.

class CarPromo
{
public string Make { get; set; }
public string Slogan { get; set; }
public CarPromo(string make, string slogan)
{
this.Make = make;
this.Slogan = slogan;
}
}

Add this getPromo code inside the Car class, right after the getInventory method.

public static List<CarPromo> GetPromos()
{
return new List<CarPromo>
{
new CarPromo("BMW", "The Ultimate driving machine"),
new CarPromo("Ford", "Go Further"),
new CarPromo("Audi","Truth in Engineering"),
new CarPromo("Acura", "Precision Crafted Performance"),
new CarPromo("Lexus", "The Relentless Pursuit of Perfection"),
new CarPromo("Mercedes Benz", "The best or nothing")
};
}

The query below is a join for the Car and CarPromo collections.

//join Car and CarPromo on make
var vehiclePromos = from c in Car.getInventory()
join p in Car.GetPromos()
on c.Make equals p.Make
select new
{
c.Make,
c.Model,
p.Slogan
};

Let’s print the result.

//print make, model, slogan
vehiclePromos.ToList().ForEach(xp =>
{
Console.WriteLine($"{xp.Make} {xp.Model} '{xp.Slogan}'");
});

That is pretty much my intro of C# LINQ to you. Start using it if you haven’t. It’ll make your experience coding in C# a lot easier.

If for any reason you ran into issues, here’s the Program.cs file with the code.

The Startup

Medium's largest active publication, followed by +563K people. Follow to join our community.

Petey

Written by

Petey

Husband, father, engineer, musician, and writer by luck. I write mostly about whatever comes to mind. Follow me on this crazy writing journey if you dare.

The Startup

Medium's largest active publication, followed by +563K people. Follow to join our community.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade