· We can write LINQ (Language Integrated Query) as two ways: 1. Method Syntax & 2. Query Syntax (similar to database query)

· Some Name of LINQ: (To view 14 type LINQ code and example https://github.com/dotnet/try-samples/tree/main/101-linq-samples/src)

NamespaceDescription
1.       AggregateOperatorsContains operators for performing aggregate operations on collections, such as Sum(), Average(), and Count().
2.       ConversionsContains operators for converting between different types of collections, such as ToList(), ToArray(), and ToDictionary().
3.       ElementOperationsContains operators for performing operations on individual elements of a collection, such as First(), Last(), and Where().
4.       GeneratorsContains operators for generating new collections from existing collections, such as Range(), Repeat(), and Empty().
5.       GroupingsContains operators for grouping elements of a collection into groups, such as GroupBy() and ToLookup().
6.       JoinOperationsContains operators for joining two or more collections together, such as Join(), GroupJoin(), and LeftJoin().
7.       OrderingsContains operators for ordering elements of a collection, such as OrderBy() and OrderByDescending().
8.       PartitionsContains operators for partitioning a collection into smaller collections, such as Skip(), Take(), and Chunk().
9.       ProjectionsContains operators for projecting elements of a collection into new values, such as Select(), SelectMany(), and Cast().
10.   QuantifiersContains operators for checking for the existence or absence of elements in a collection, such as Any(), All(), and Contains().
11.   QueryExecutionContains interfaces and classes for executing LINQ queries.
12.   RestrictionsContains operators for restricting the elements of a collection, such as Where() and SkipWhile().
13.   SequenceOperationsContains operators for performing operations on sequences of elements, such as Concat(), Union(), and Except().
14.   SetOperationsContains operators for performing set operations on collections, such as Intersect() and IsSubsetOf().

1. Aggregate Operators Example

// Method syntax
var sum = numbers.Sum();
// Query syntax
var sum = (from n in numbers select n).Sum();

Here’s the formatted code based on your provided examples:

2. Conversions Example

// Method syntax
var list = numbers.ToList();
// Query syntax
var list = (from n in numbers select n).ToList();

3. Element Operations Example

// Method syntax
var first = numbers.First();
// Query syntax
var first = (from n in numbers select n).First();

4. Generators Example

// Method syntax
var range = Enumerable.Range(1, 10);
// Query syntax
var range = from i in Enumerable.Range(1, 10) select i;

5. Grouping Example

// Method syntax
var groups = numbers.GroupBy(n => n % 2 == 0);
// Query syntax
var groups = from n in numbers group n by n % 2 == 0;

6. Join Operation Example

// Method syntax
var join = customers.Join(orders, c => c.Id, o => o.CustomerId, (c, o) => new { Customer = c, Order = o });
// Query syntax
var join = from c in customers join o in orders on c.Id equals o.CustomerId select new { Customer = c, Order = o };

7. Ordering Operations Example

// Method syntax
var ordered = numbers.OrderBy(n => n);
// Query syntax
var ordered = from n in numbers orderby n select n;

8. Partition Example

// Method syntax
var firstFive = numbers.Take(5);
// Query syntax
var firstFive = (from n in numbers select n).Take(5);

9. Projection Example

// Method syntax
var lengths = numbers.Select(n => n.ToString().Length);
// Query syntax
var lengths = from n in numbers select n.ToString().Length;

10. Quantifiers Example

// Method syntax
var hasNegative = numbers.Any(n => n < 0);
// Query syntax
var hasNegative = (from n in numbers where n < 0 select n).Any();

11. Query Executions Example

// Deferred execution
var query = from n in numbers where n <= 3 select n;
// Eager execution
var results = query.ToList();

12. Restrictions Example

// Method syntax
var filtered = numbers.Where(n => n <= 3);
// Query syntax
var filtered = from n in numbers where n <= 3 select n;

· Practice 3 Question:

Task 1: In this task, write a Linq query to print all students and their course name, like: “Jalaluddin, C#” “Hasan, Asp.net”

// Question
List<(int id, string name, double price)> courses = new List<(int id, string name, double price)>();
courses.Add((1, "C#", 8000));
courses.Add((2, "Asp.net", 30000));
 
List<(int id, string name, string address, int courseId)> students = new List<(int id, string name, string address, int courseId)>();
students.Add((3, "Jalaluddin", "Mirpur", 2));
students.Add((4, "Hasan", "Moghbazar", 1));
 
 
 
// Answer
// Query Syntax
var resultQuery = from x in students
                join y in courses
                on x.courseId equals y.id
                // where x.price > 10000
                select $"{x.name}, {y.name}";
foreach(var z in resultQuery)
    Console.WriteLine(z);
 
// Method Syntax
var resultMethod = students.Join(courses, x => x.courseId, y => y.id, (x, y) => $"{x.name}, {y.name}");
foreach(var z in resultMethod)
    Console.WriteLine(z);
 
 
// We can convert it into mssql query
SELECT c.name AS CourseName, s.name AS StudentName
FROM courses c
JOIN students s ON c.id = s.courseId
WHERE c.price > 10000;
 
SELECT COUNT(*) AS ResultCount
FROM courses c
JOIN students s ON c.id = s.courseId
WHERE c.price > 10000;

Task 2: In this task, write a Linq query to print all person data sorted according to name first and then by age (in case name is same). Print both name and age.

// Question
List<(int id, string name, int age)> persons = new List<(int id, string name, int age)>();
persons.Add((1, "Jalaluddin", 42));
persons.Add((2, "Hasan", 32));
persons.Add((3, "Maruf", 23));
 
// Answer
// Method Syntax
var sortedMethod = persons.OrderBy(x => x.name).ThenBy(x => x.age);
foreach (var x in sortedMethod)
    Console.WriteLine(x);
    
// Query Syntax
var sortedQuery = from x in persons orderby x.name, x.age select x;
foreach (var x in sortedQuery)
    Console.WriteLine(x);
// Convert it into sql
SELECT *
FROM persons
ORDER BY name, age;

Task 3: In this task, you have to print the names of fruits grouped by their last letter. Print the last letter and the fruits that belong to that letter.

// Question
string[] fruits = { "apple", "banana", "mango", "goava", "strawberry", "pineapple" };
 
// Answer
// Method Syntax
var groupResultMethod = fruits.GroupBy(x => x.Last());
foreach (var x in groupResultMethod)
{
    Console.WriteLine("Last letter is: " + x.Key);
    foreach (var y in x)
        Console.WriteLine(y);
}
 
// Query Syntax
 
// Method Syntax
var groupResultMethod = fruits.GroupBy(x => x.Last());
foreach (var x in groupResultMethod)
{
    Console.WriteLine("Last letter is: " + x.Key);
    foreach (var y in x)
        Console.WriteLine(y);
}
 
// Query Syntax
var groupResultQuery =
    from x in fruits
    group x by x[x.Length - 1] into g
    select (LastLetter: g.Key, Words: g);
foreach (var x in groupResultQuery)
{
    Console.WriteLine("Last letter is: " + x.LastLetter);
    foreach (var y in x.Words)
        Console.WriteLine(y);
}

Interview Question: Findout count, name and age from list where age>=25 && age 26

 
List<(string name, int age)> bios = new List<(string name, int age)>();
 
bios.Add(("MSA", 23));
bios.Add(("Shoyeb", 24));
bios.Add(("MSA2", 25));
bios.Add(("MSA3", 26));
bios.Add(("MSA4", 27));
bios.Add(("MSA5", 28));
 
// Method Query
var biosResultMethod = bios.Where(x => x.age >= 25 && x.age <= 26);
foreach (var x in biosResultMethod)
    Console.WriteLine("Name: {0}, Age: {1}", x.name, x.age);
Console.WriteLine("Total count: " + biosResultMethod.Count());
 
// Syntax Query
var biosResultQuery = from x in bios where x.age >= 25 && x.age <= 26 select x;
foreach (var x in biosResultQuery)
    Console.WriteLine("Name: {0}, Age: {1}", x.name, x.age);
Console.WriteLine("Total count: " + biosResultQuery.Count());

1. Aggregate Operators Example

// More Example from github 101
int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0, 11, 14, 17, 20 };
// Count distinct elements
int uniqueFactors = numbers.Distinct().Count();
Console.WriteLine($"Count of distinct elements: {uniqueFactors}");
 
// Count odd numbers
int oddNumbers = numbers.Count(n => n % 2 == 1);
Console.WriteLine($"Count of odd numbers: {oddNumbers}");
 
// Sum of all numbers
double numSum = numbers.Sum();
Console.WriteLine($"Sum of numbers: {numSum}");
 
// Minimum number
int minNum = numbers.Min();
Console.WriteLine($"Minimum number: {minNum}");
 
// Maximum number
int maxNum = numbers.Max();
Console.WriteLine($"Maximum number: {maxNum}");
 
// Average of all numbers
double averageNum = numbers.Average();
Console.WriteLine($"Average of numbers: {averageNum}");
 
double[] doubles = { 1.7, 2.3, 1.9, 4.1, 2.9 };
 
// Calculate the total product of all numbers (Aggregate means সমষ্টি)
double product = doubles.Aggregate((runningProduct, nextFactor) => runningProduct * nextFactor);
Console.WriteLine($"Total product of all numbers: {product}");
 
string[] words = { "cherry", "apple", "blueberry" };
 
// Total characters in all words
double totalChars = words.Sum(w => w.Length);
Console.WriteLine($"Total characters in all words: {totalChars}");
 
// Length of the shortest word
int shortestWord = words.Min(w => w.Length);
Console.WriteLine($"Length of the shortest word: {shortestWord}");
 
// Length of the longest word
int longestLength = words.Max(w => w.Length);
Console.WriteLine($"Length of the longest word: {longestLength}");
 
// Average length of words
double averageLength = words.Average(w => w.Length);
Console.WriteLine($"Average length of words: {averageLength}");

2. Conversions Example

double[] doubles = { 1.7, 2.3, 1.9, 4.1, 2.9 };
var sorted = from x in doubles orderby x descending select x;
var sortedArray = sorted.ToArray();
foreach (var x in sortedArray)
    Console.WriteLine(x);
 
string[] words = { "cherry", "apple", "blueberry" };
var sortedWords = from x in words orderby x select x;
var wordList = sortedWords.ToList();
foreach (var x in wordList)
    Console.WriteLine(x);
 
var scoreRecords = new[]
{
    new { Name = "MSA", Score = 30 },
    new { Name = "Shoyeb", Score = 10 },
    new { Name = "Sr", Score = 20 }
};
var scoreRecordsDictionary = scoreRecords.ToDictionary(x => x.Name);
Console.WriteLine("Shoyeb's score: {0}", scoreRecordsDictionary["Shoyeb"]);
 
object[] numbers = { null, 1.0, "two", 3, "four", 5, "six", 7.0 };
var doubles = numbers.OfType<double>(); // int, string all supported
foreach (var d in doubles)
{
    Console.WriteLine(d);
}

3. Element Operations Example

string[] strings =
{
    "zero",
    "one",
    "onion",
    "two",
    "three",
    "four",
    "five",
    "six",
    "seven",
    "eight",
    "nine"
};
 
var startsWithO = strings.First(s => s[0] == 'o');
Console.WriteLine($"A string starting with 'o': {startsWithO}");
 
int[] numbers = { };
int firstNumOrDefault = numbers.FirstOrDefault();
Console.WriteLine(firstNumOrDefault);
 
int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
int fourthLowNum = (from x in numbers where x > 7 select x).ElementAt(1);
Console.WriteLine($"Second number > 7: {fourthLowNum}"); // second number is index 1 because sequences use 0-based indexing

4. Generators Example

var numbers =
    from n in Enumerable.Range(100, 50)
    select (Number: n, OddEven: n % 2 == 1 ? "odd" : "even");
 
foreach (var n in numbers)
{
    Console.WriteLine("The number {0} is {1}.", n.Number, n.OddEven);
}
 
var numbersRepeat = Enumerable.Repeat(7, 10);
 
foreach (var n in numbersRepeat)
{
    Console.WriteLine(n);
}

5. Grouping Example

int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
var numberGroup = from x in numbers group x by x % 5 into g select (Remainder: g.Key, Group: g);
foreach (var x in numberGroup)
{
    Console.WriteLine($"Number with a remainder of {x.Remainder} when divide by 5:");
    foreach (var y in x.Group)
        Console.WriteLine(y);
}
 
string[] words = { "blueberry", "chimpanzee", "abacus", "banana", "apple", "cheese" };
var wordGroups = from x in words group x by x[0] into g select (FirstLetter: g.Key, Words: g);
foreach (var x in wordGroups)
{
    Console.WriteLine("Words that start with the letter '{0}':", x.FirstLetter);
    foreach (var y in x.Words)
    {
        Console.WriteLine(y);
    }
}
 
string[] anagrams = { "from   ", " salt", " earn ", "  last   ", " near ", " form  " };
 
var orderGroups = anagrams.GroupBy(w => w.Trim(), new AnagramEqualityComparer());
foreach (var set in orderGroups)
{
    // The key would be the first item in the set
    foreach (var word in set)
    {
        Console.WriteLine(word);
    }
    Console.WriteLine("...");
}
 
var orderGroups2 = anagrams.GroupBy(w => w.Trim(), a => a.ToUpper(), new AnagramEqualityComparer());
foreach (var set in orderGroups2)
{
    Console.WriteLine(set.Key);
    foreach (var word in set)
    {
        Console.WriteLine($"\t{word}");
    }
}
 
public class AnagramEqualityComparer : IEqualityComparer<string>
{
    public bool Equals(string x, string y) => getCanonicalString(x) == getCanonicalString(y);
 
    public int GetHashCode(string obj) => getCanonicalString(obj).GetHashCode();
 
    private string getCanonicalString(string word)
    {
        char[] wordChars = word.ToCharArray();
        Array.Sort<char>(wordChars);
        return new string(wordChars);
    }
}

6. Join Operation Example

// Example not provided, please insert a join operation example here.

7. Ordering Operations Example

string[] words = { "cherry", "apple", "blueberry" };
var sortedWords = from word in words orderby word select word;
Console.WriteLine("The sorted list of words:");
foreach (var w in sortedWords)
{
    Console.WriteLine(w);
}
 
var sortedWords2 = from word in words orderby word.Length select word;
Console.WriteLine("The sorted list of words (by length):");
foreach (var w in sortedWords2)
{
    Console.WriteLine(w);
}
 
double[] doubles = { 1.7, 2.3, 1.9, 4.1, 2.9 };
var sortedDoubles = from d in doubles orderby d descending select d;
Console.WriteLine("The doubles from highest to lowest:");
foreach (var d in sortedDoubles)
{
    Console.WriteLine(d);
}
 
string[] digits =
{
    "zero",
    "one",
    "two",
    "three",
    "four",
    "five",
    "six",
    "seven",
    "eight",
    "nine"
};
 
var sortedDigits = from digit in digits orderby digit.Length, digit select digit;
Console.WriteLine("Sorted digits:");
foreach (var d in sortedDigits)
{
    Console.WriteLine(d);
}
 
var reversedIDigits = (from digit in digits where digit[1] == 'i' select digit).Reverse();
Console.WriteLine("A backwards list of the digits with a second character of 'i':");
foreach (var d in reversedIDigits)
{
    Console.WriteLine(d);
}
 
string[] words2 = { "aPPLE", "AbAcUs", "bRaNcH", "BlUeBeRrY", "ClOvEr", "cHeRry" };
var sortedWords3 = words2.OrderBy(a => a, new CaseInsensitiveComparer());
foreach (var word in sortedWords3)
{
    Console.WriteLine(word);
}
 
public class CaseInsensitiveComparer : IComparer<string>
{
    public int Compare(string x, string y) =>
        string.Compare(x, y, StringComparison.OrdinalIgnoreCase);
}

8. Partition Example

int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
var first3Numbers = numbers.Take(3);
Console.WriteLine("First 3 numbers:");
foreach (var n in first3Numbers)
{
    Console.WriteLine(n);
}
 
int[] numbers2 = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
var allButFirst4Numbers = numbers2.Skip(4);
Console.WriteLine("All but first 4 numbers:");
foreach (var n in allButFirst4Numbers)
{
    Console.WriteLine(n);
}
 
int[] numbers3 = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
var firstNumbersLessThan6 = numbers3.TakeWhile(n => n < 6);
Console.WriteLine("First numbers less than 6:");
foreach (var num in firstNumbersLessThan6)
{
    Console.WriteLine(num);
}
 
int[] numbers4 = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
var firstSmallNumbers = numbers4.TakeWhile((n, index) => n >= index);
Console.WriteLine("First numbers not less than their position:");
foreach (var n in firstSmallNumbers)
{
    Console.WriteLine(n);
}

9. Projection Example

int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
var numsPlusOne = from n in numbers select n + 1;
Console.WriteLine("Numbers + 1:");
foreach (var i in numsPlusOne)
{
    Console.WriteLine(i);
}
 
int[] numbers2 = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
string[] strings =
{
    "zero",
    "one",
    "two",
    "three",
    "four",
    "five",
    "six",
    "seven",
    "eight",
    "nine"
};
var textNums = from n in numbers2 select strings[n];
Console.WriteLine("Number strings:");
foreach (var s in textNums)
{
    Console.WriteLine(s);
}
 
string[] words = { "aPPLE", "BlUeBeRrY", "cHeRry" };
var upperLowerWords = from w in words select new { Upper = w.ToUpper(), Lower = w.ToLower() };
foreach (var ul in upperLowerWords)
{
    Console.WriteLine($"Uppercase: {ul.Upper}, Lowercase: {ul.Lower}");
}
 
int[] numbers3 = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
string[] strings3 =
{
    "zero",
    "one",
    "two",
    "three",
    "four",
    "five",
    "six",
    "seven",
    "eight",
    "nine"
};
var digitOddEvens = from n in numbers3 select new { Digit = strings3[n], Even = (n % 2 == 0) };
foreach (var d in digitOddEvens)
{
    Console.WriteLine($"The digit {d.Digit} is {(d.Even ? "even" : "odd")}.");
}
 
int[] numbers4 = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
var numsInPlace = numbers4.Select((num, index) => (Num: num, InPlace: (num == index)));
Console.WriteLine("Number: In-place?");
foreach (var n in numsInPlace)
{
    Console.WriteLine($"{n.Num}: {n.InPlace}");
}
 
int[] numbersA = { 0, 2, 4, 5, 6, 8, 9 };
int[] numbersB = { 1, 3, 5, 7, 8 };
var pairs = from a in numbersA from b in numbersB where a < b select (a, b);
Console.WriteLine("Pairs where a < b:");
foreach (var pair in pairs)
{
    Console.WriteLine($"{pair.a} is less than {pair.b}");
}

10. Quantifiers Example

string[] words = { "believe", "relief", "receipt", "field" };
bool iAfterE = words.Any(w => w.Contains("ei"));
Console.WriteLine($"There is a word that contains in the list that contains 'ei': {iAfterE}");
 
int[] numbers = { 1, 11, 3, 19, 41, 65, 19 };
bool onlyOdd = numbers.All(n => n % 2 == 1);
Console.WriteLine($"The list contains only odd numbers: {onlyOdd}");

11. Query Executions Example

int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
int i = 0;
var counter = from x in numbers select ++i;
foreach (var x in counter)
{
    Console.WriteLine($"x = {x}, i = {i}");
}
 
int j = 0;
var counter2 = (from n in numbers select ++j).ToList();
foreach (var x in counter2)
{
    Console.WriteLine($"x = {x}, i = {j}");
}

12. Restrictions Example

int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
var lowNums = from num in numbers where num < 5 select num;
Console.WriteLine("Numbers < 5:");
foreach (var x in lowNums)
{
    Console.WriteLine(x);
}
 
string[] digits =
{
    "zero",
    "one",
    "two",
    "three",
    "four",
    "five",
    "six",
    "seven",
    "eight",
    "nine"
};
 
var shortDigits = digits.Where((digit, index) => digit.Length < index);
Console.WriteLine("Short digits:");
foreach (var d in shortDigits)
{
    Console.WriteLine($"The word {d} is shorter than its value.");
}

13. Sequence Operation Example

var wordsA = new string[] { "cherry", "apple", "blueberry" };
var wordsB = new string[] { "cherry", "apple", "blueberry" };
bool match = wordsA.SequenceEqual(wordsB);
Console.WriteLine($"The sequences match: {match}");
 
int[] numbersA = { 0, 2, 4, 5, 6, 8, 9 };
int[] numbersB = { 1, 3, 5, 7, 8 };
var allNumbers = numbersA.Concat(numbersB);
Console.WriteLine("All numbers from both arrays:");
foreach (var n in allNumbers)
{
    Console.WriteLine(n);
}
 
int[] vectorA = { 0, 2, 4, 5, 6 };
int[] vectorB = { 1, 3, 5, 7, 8 };
int dotProduct = vectorA.Zip(vectorB, (a, b) => a * b).Sum();
Console.WriteLine($"Dot product: {dotProduct}");

14. Set operation Example

int[] factorsOf300 = { 2, 2, 3, 5, 5 };
var uniqueFactors = factorsOf300.Distinct();
Console.WriteLine("Prime factors of 300:");
foreach (var f in uniqueFactors)
{
    Console.WriteLine(f);
}
 
int[] numbersA = { 0, 2, 4, 5, 6, 8, 9 };
int[] numbersB = { 1, 3, 5, 7, 8 };
var uniqueNumbers = numbersA.Union(numbersB);
Console.WriteLine("Unique numbers from both arrays:");
foreach (var n in uniqueNumbers)
{
    Console.WriteLine(n);
}
 
int[] numbersA2 = { 0, 2, 4, 5, 6, 8, 9 };
int[] numbersB2 = { 1, 3, 5, 7, 8 };
var commonNumbers = numbersA2.Intersect(numbersB2);
Console.WriteLine("Common numbers shared by both arrays:");
foreach (var n in commonNumbers)
{
    Console.WriteLine(n);
}
 
int[] numbersA3 = { 0, 2, 4, 5, 6, 8, 9 };
int[] numbersB3 = { 1, 3, 5, 7, 8 };
IEnumerable<int> aOnlyNumbers = numbersA3.Except(numbersB3);
Console.WriteLine("Numbers in first array but not second array:");
foreach (var n in aOnlyNumbers)
{
    Console.WriteLine(n);
}