C# LINQ Exploring
Tags: csharp, backend
Published: 2023-07-06 10:26:33

SOURCE CODE:
https://github.com/SomAniac0/Academy

## LINQ definition:

- Language-Integrated Query (LINQ) is a powerful set of technologies based on the integration of query capabilities directly into the C# language. LINQ Queries are the first-class language construct in C# .NET, just like classes, methods, events.
- The LINQ provides a consistent query experience to query objects (LINQ to Objects), relational databases (LINQ to SQL), and XML (LINQ to XML).

## How it works?

![HowItWorks](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g9y0vek1352vdps1q9s0.png)


Creating a simple Employee class.
```
public class Employee
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public decimal AnnualSalary { get; set; }
        public bool IsManager { get; set; }
        public int DepartmentId { get; set; }
    }
```

Creating a custom Filter LINQ like function.
```
public static class Extension
    {
        public static List<T> Filter<T>(this List<T> records, Func<T,bool> func)
        {
            List<T> filteredList = new List<T>();

            foreach (T record in records) 
            {
                if (func(record))
                {
                    filteredList.Add(record);
                }
            }

            return filteredList;
        }
    }
```

Based on the evaluation of the delegate function we get the managers.
```
var filteredEmployees = employeeList.Filter(e => e.IsManager == true);

```
Basically your linq expression is being compiled into generic classes, and Expression trees. Always be mindful which linq function you use, because there are big performance differences if you choose a wrong one or you implement it in an unoptimized way.

## Syntax difference and Lazy/Eager Loading

- Choose Query Syntax IF possible for easy readability otherwise stick to function syntax.

- While lazy loading delays the initialization of a resource, eager loading initializes or loads a resource as soon as the code is executed.


```
// LINQ Query Syntax lazy loading
var queryLazyResult = from emp in employeeList
             where emp.IsManager == true
             select emp.FirstName;

// LINQ Query Syntax Eager loading
var queryEagerResult = (from emp in employeeList
                  where emp.IsManager == true
                  select emp.FirstName).ToList();

// LINQ Method Syntax lazy loading
var functionLazyResult = employeeList.Where(e => e.IsManager == true);

// LINQ Method Syntax Eager loading
var functionEagerResult = employeeList.Where(e => e.IsManager == true).ToList();

// Test Employee added for lazy-eager loading
employeeList.Add(new Employee() { IsManager = true});

var querylazyCount = queryLazyResult.Count();               //8
var functionLazyCount = functionLazyResult.Count();         //8  
var queryEagerCount = queryEagerResult.Count();             //7
var functionEagerCount = functionEagerResult.Count();       //7
```
In this case after declaration adding one element means 7 element in eager loading and 8 in lazy.

## IQueryable<T> vs IEnumerable<T>

- The major difference between IQueryable and IEnumerable is that IQueryable executes query with filters whereas IEnumerable executes the query first and then it filters the data based on conditions.

With other words:

- IEnumerable<T> interface is useful when your collection is loaded in memory using LINQ or Entity framework and you want to apply filter on the collection.

- IQueryable<T>: best suits for remote data source, like a database or web service (or remote queries). IQueryable is a very powerful feature that enables a variety of interesting deferred execution scenarios (like paging and composition based queries). With simple words IEnumerable executes the query then filters it on client side, IQueryable does the filtering on server side.

2 example:
```
IQueryable<Employee> MethodSyntax = employeeList.AsQueryable().Where(emp => emp.IsManager == true); 
IEnumerable<Employee> iEnumerable = employeeList.Where(emp => emp.IsManager == true);
```

## Performance

- To summarize it first for lazy colleagues. For small data setts performance difference wont hit hard. But you should keep in mind that LINQ is not always the best solution for every task.

- For example it works extremely well with Group By but because of recent VSD (Virtual Stub Dispatch) based Interface casting make it very expensive. Soo getting the Last() element of a list takes 3 times more time with linq then simply using x = list[list.Count - 1].

In the source code there are some simple performance measurements:
https://github.com/SomAniac0/Academy

If you are interested in benchmarks with different libraries and approaches then go here:
https://github.com/NetFabric/LinqBenchmarks






## Sources and recommended channels
- https://www.youtube.com/watch?v=5l2qA3Pc83M&t=2237s
- https://www.youtube.com/@LevelUppp
- https://www.tutorialsteacher.com/linq/what-is-linq