Chapter 19: LINQ (Language Integrated Query)
1. What is LINQ? (Super Simple Analogy)
Think of LINQ like Google search for your data:
- You have a big list of students, products, orders, employees…
- Instead of writing 10–20 lines of for loops, if conditions, sorting code…
- You write one clean, readable line that says: “Give me all students from Hyderabad, sorted by age, show only their names”
LINQ does all the heavy lifting for you!
2. Two Ways to Write LINQ
There are two syntaxes – both do exactly the same thing:
| Style | Looks like | Most people prefer because… |
|---|---|---|
| Query Syntax | Like SQL (from … where … select) | Very readable, especially for complex queries |
| Method Syntax | Chained methods (.Where().OrderBy().Select()) | Very powerful, great for chaining, lambdas |
Important: Both are 100% equivalent – the compiler turns query syntax into method syntax behind the scenes.
3. Our Sample Data – Students List
Let’s use this list for all examples:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
var students = new List<Student> { new Student { Id = 1, Name = "Rahul", Age = 22, City = "Hyderabad", Marks = 85 }, new Student { Id = 2, Name = "Priya", Age = 21, City = "Delhi", Marks = 92 }, new Student { Id = 3, Name = "Amit", Age = 24, City = "Mumbai", Marks = 78 }, new Student { Id = 4, Name = "Sneha", Age = 23, City = "Hyderabad", Marks = 95 }, new Student { Id = 5, Name = "Vikram",Age = 20, City = "Bangalore", Marks = 88 } }; class Student { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } public string City { get; set; } public int Marks { get; set; } } |
4. Basic Filtering – Where
Query Syntax:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 |
var hyderabadStudents = from s in students where s.City == "Hyderabad" select s.Name; foreach (var name in hyderabadStudents) { Console.WriteLine(name); // Rahul, Sneha } |
Method Syntax:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 |
var hyderabadStudents = students .Where(s => s.City == "Hyderabad") .Select(s => s.Name); foreach (var name in hyderabadStudents) { Console.WriteLine(name); // Rahul, Sneha } |
5. Ordering – OrderBy, ThenBy
Query Syntax:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 |
var sortedByMarks = from s in students orderby s.Marks descending, s.Age select new { s.Name, s.Marks, s.Age }; foreach (var s in sortedByMarks) { Console.WriteLine($"{s.Name}: {s.Marks}% (Age {s.Age})"); } |
Method Syntax:
|
0 1 2 3 4 5 6 7 8 9 |
var sortedByMarks = students .OrderByDescending(s => s.Marks) .ThenBy(s => s.Age) .Select(s => new { s.Name, s.Marks, s.Age }); |
Output:
|
0 1 2 3 4 5 6 7 8 9 10 |
Sneha: 95% (Age 23) Priya: 92% (Age 21) Vikram: 88% (Age 20) Rahul: 85% (Age 22) Amit: 78% (Age 24) |
6. Grouping – GroupBy
Query Syntax:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
var studentsByCity = from s in students group s by s.City into cityGroup select new { City = cityGroup.Key, Count = cityGroup.Count(), Names = string.Join(", ", cityGroup.Select(s => s.Name)) }; foreach (var group in studentsByCity) { Console.WriteLine($"{group.City} ({group.Count} students): {group.Names}"); } |
Method Syntax:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 |
var studentsByCity = students .GroupBy(s => s.City) .Select(g => new { City = g.Key, Count = g.Count(), Names = string.Join(", ", g.Select(s => s.Name)) }); |
Output:
|
0 1 2 3 4 5 6 7 8 9 |
Hyderabad (2 students): Rahul, Sneha Delhi (1 students): Priya Mumbai (1 students): Amit Bangalore (1 students): Vikram |
7. Joining – Join (Like SQL JOIN)
Example: Students + Cities with population
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
var cities = new List<CityInfo> { new CityInfo { Name = "Hyderabad", Population = 10000000 }, new CityInfo { Name = "Delhi", Population = 30000000 }, new CityInfo { Name = "Mumbai", Population = 20000000 } }; class CityInfo { public string Name { get; set; } public int Population { get; set; } } |
Query Syntax (Inner Join):
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 |
var studentCities = from s in students join c in cities on s.City equals c.Name select new { s.Name, City = s.City, Population = c.Population }; |
Method Syntax:
|
0 1 2 3 4 5 6 7 8 9 10 |
var studentCities = students .Join(cities, s => s.City, c => c.Name, (s, c) => new { s.Name, City = s.City, Population = c.Population }); |
8. Deferred Execution – The Magic of LINQ!
Very important concept:
Most LINQ queries do NOT execute immediately – they wait until you iterate over them (with foreach, .ToList(), .Count(), etc.).
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
var query = students.Where(s => s.Marks > 90); // Nothing has happened yet! Console.WriteLine("Query created..."); // Now it executes! foreach (var s in query) { Console.WriteLine(s.Name); // Priya, Sneha } |
Why is this useful?
- You can build a query step-by-step
- It only runs once when needed
- Very efficient!
Force execution immediately:
|
0 1 2 3 4 5 6 |
var immediate = students.Where(s => s.Marks > 90).ToList(); // Executes now! |
Mini-Project: Student Report Generator with LINQ
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
Console.WriteLine("=== Student Report (LINQ Power) ===\n"); // 1. Top 3 students by marks var topStudents = students .OrderByDescending(s => s.Marks) .Take(3) .Select(s => $"{s.Name} ({s.Marks}%) from {s.City}"); Console.WriteLine("Top 3 Students:"); foreach (var s in topStudents) { Console.WriteLine(s); } // 2. Average marks per city var avgByCity = students .GroupBy(s => s.City) .Select(g => new { City = g.Key, AverageMarks = g.Average(s => s.Marks), StudentCount = g.Count() }); Console.WriteLine("\nAverage Marks by City:"); foreach (var g in avgByCity) { Console.WriteLine($"{g.City}: {g.AverageMarks:F1}% ( {g.StudentCount} students )"); } // 3. Students from Hyderabad or above 90 marks var specialStudents = from s in students where s.City == "Hyderabad" || s.Marks >= 90 orderby s.Marks descending select s.Name; Console.WriteLine("\nSpecial Students (Hyderabad or 90+ marks):"); Console.WriteLine(string.Join(", ", specialStudents)); |
Output:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
=== Student Report (LINQ Power) === Top 3 Students: Sneha (95%) from Hyderabad Priya (92%) from Delhi Vikram (88%) from Bangalore Average Marks by City: Hyderabad: 90.0% ( 2 students ) Delhi: 92.0% ( 1 students ) Mumbai: 78.0% ( 1 students ) Bangalore: 88.0% ( 1 students ) Special Students (Hyderabad or 90+ marks): Sneha, Priya, Rahul |
Summary – What We Learned Today
- LINQ = Language Integrated Query – query data like SQL inside C#
- Query syntax → looks like SQL (from … where … select)
- Method syntax → chained methods (.Where().OrderBy().Select())
- Filtering (Where), Ordering (OrderBy), Grouping (GroupBy), Joining (Join)
- Deferred execution → query runs only when you iterate (foreach, .ToList(), etc.)
- Anonymous types → new { s.Name, s.Marks } – perfect for temporary results
Your Homework (Super Fun & Practical!)
- Create a new console project called LinqMaster
- Create a list of Products with: Name, Price, Category, Stock
- Write LINQ queries (both syntaxes) to:
- Get all products under ₹500 sorted by price
- Group products by Category and show average price per category
- Find products with stock < 10 (low stock alert)
- Join with a list of Categories that have discounts
- Bonus: Use Take(5), Skip(3), FirstOrDefault(), Any(), All()
Next lesson: File I/O and Serialization – we’re going to learn how to read/write files, save data to JSON, and make your programs persistent!
You’re doing absolutely fantastic! 🎉 Any part confusing? Want more LINQ examples (grouping, joining, set operations)? Just tell me — I’m right here for you! 💙
