Claude
Skills
Sign in
Back

csharp-linq

Included with Lifetime
$97 forever

Use when lINQ (Language Integrated Query) with query and method syntax, deferred execution, expression trees, and performance optimization.

General

What this skill does


# C# LINQ

LINQ (Language Integrated Query) provides a consistent query experience across
different data sources including collections, databases, XML, and more. It
combines the power of SQL-like queries with C# type safety and IntelliSense
support, enabling expressive and maintainable data manipulation code.

## Query Syntax

Query syntax provides SQL-like syntax for querying data sources, compiled to
method calls at compile time.

```csharp
using System;
using System.Collections.Generic;
using System.Linq;

public class QuerySyntaxExamples
{
    public record Person(string Name, int Age, string City);

    // Basic query
    public IEnumerable<Person> BasicQuery(List<Person> people)
    {
        var query = from p in people
                    where p.Age >= 18
                    select p;

        return query;
    }

    // Query with multiple conditions
    public IEnumerable<Person> MultipleConditions(List<Person> people)
    {
        var query = from p in people
                    where p.Age >= 18 && p.City == "Seattle"
                    orderby p.Name
                    select p;

        return query;
    }

    // Projection with select
    public IEnumerable<string> ProjectNames(List<Person> people)
    {
        var query = from p in people
                    where p.Age >= 21
                    select p.Name;

        return query;
    }

    // Anonymous types
    public IEnumerable<object> AnonymousProjection(List<Person> people)
    {
        var query = from p in people
                    select new
                    {
                        p.Name,
                        p.Age,
                        IsAdult = p.Age >= 18
                    };

        return query;
    }

    // Grouping
    public IEnumerable<IGrouping<string, Person>> GroupByCity(
        List<Person> people)
    {
        var query = from p in people
                    group p by p.City;

        return query;
    }

    // Group with projection
    public IEnumerable<object> GroupWithProjection(List<Person> people)
    {
        var query = from p in people
                    group p by p.City into cityGroup
                    select new
                    {
                        City = cityGroup.Key,
                        Count = cityGroup.Count(),
                        AverageAge = cityGroup.Average(p => p.Age)
                    };

        return query;
    }

    // Join
    public record Order(int Id, string PersonName, decimal Amount);

    public IEnumerable<object> JoinExample(
        List<Person> people,
        List<Order> orders)
    {
        var query = from p in people
                    join o in orders on p.Name equals o.PersonName
                    select new
                    {
                        p.Name,
                        p.Age,
                        OrderAmount = o.Amount
                    };

        return query;
    }

    // Left join
    public IEnumerable<object> LeftJoin(
        List<Person> people,
        List<Order> orders)
    {
        var query = from p in people
                    join o in orders on p.Name equals o.PersonName
                    into personOrders
                    from po in personOrders.DefaultIfEmpty()
                    select new
                    {
                        p.Name,
                        OrderAmount = po?.Amount ?? 0
                    };

        return query;
    }
}
```

## Method Syntax

Method syntax uses extension methods for querying, providing more flexibility
and access to all LINQ operators.

```csharp
using System;
using System.Collections.Generic;
using System.Linq;

public class MethodSyntaxExamples
{
    public record Product(string Name, decimal Price, string Category);

    // Filtering
    public IEnumerable<Product> FilterProducts(List<Product> products)
    {
        return products
            .Where(p => p.Price > 100)
            .Where(p => p.Category == "Electronics");
    }

    // Ordering
    public IEnumerable<Product> OrderProducts(List<Product> products)
    {
        return products
            .OrderBy(p => p.Category)
            .ThenByDescending(p => p.Price);
    }

    // Projection
    public IEnumerable<string> ProjectNames(List<Product> products)
    {
        return products
            .Select(p => p.Name.ToUpper());
    }

    // SelectMany (flatten)
    public IEnumerable<int> FlattenLists()
    {
        var lists = new List<List<int>>
        {
            new List<int> { 1, 2, 3 },
            new List<int> { 4, 5 },
            new List<int> { 6, 7, 8, 9 }
        };

        return lists.SelectMany(list => list);
    }

    // Grouping
    public IEnumerable<IGrouping<string, Product>> GroupByCategory(
        List<Product> products)
    {
        return products.GroupBy(p => p.Category);
    }

    // Aggregation
    public void AggregationExamples(List<Product> products)
    {
        decimal total = products.Sum(p => p.Price);
        decimal average = products.Average(p => p.Price);
        decimal max = products.Max(p => p.Price);
        decimal min = products.Min(p => p.Price);
        int count = products.Count();
        int expensiveCount = products.Count(p => p.Price > 500);
    }

    // Any and All
    public void ExistenceChecks(List<Product> products)
    {
        bool hasExpensive = products.Any(p => p.Price > 1000);
        bool allAffordable = products.All(p => p.Price < 100);
        bool hasElectronics = products.Any(p =>
            p.Category == "Electronics");
    }

    // Take and Skip
    public IEnumerable<Product> Pagination(
        List<Product> products,
        int page,
        int pageSize)
    {
        return products
            .OrderBy(p => p.Name)
            .Skip((page - 1) * pageSize)
            .Take(pageSize);
    }

    // Distinct
    public IEnumerable<string> UniqueCategories(List<Product> products)
    {
        return products
            .Select(p => p.Category)
            .Distinct();
    }

    // Set operations
    public void SetOperations(
        List<Product> products1,
        List<Product> products2)
    {
        var union = products1.Union(products2);
        var intersect = products1.Intersect(products2);
        var except = products1.Except(products2);
    }
}
```

## Deferred Execution

LINQ queries use deferred execution, meaning the query executes when
enumerated, not when defined.

```csharp
using System;
using System.Collections.Generic;
using System.Linq;

public class DeferredExecutionExamples
{
    // Deferred execution demonstration
    public void DeferredExecutionDemo()
    {
        var numbers = new List<int> { 1, 2, 3, 4, 5 };

        // Query defined but not executed
        var query = numbers.Where(n => n > 2);

        Console.WriteLine("Before modification:");
        foreach (var n in query)  // Executes here
        {
            Console.WriteLine(n);  // 3, 4, 5
        }

        // Modify source
        numbers.Add(6);
        numbers.Add(7);

        Console.WriteLine("After modification:");
        foreach (var n in query)  // Executes again with new data
        {
            Console.WriteLine(n);  // 3, 4, 5, 6, 7
        }
    }

    // Immediate execution with ToList
    public void ImmediateExecution()
    {
        var numbers = new List<int> { 1, 2, 3, 4, 5 };

        // Execute immediately and cache results
        var list = numbers.Where(n => n > 2).ToList();

        numbers.Add(6);
        numbers.Add(7);

        // list still contains only 3, 4, 5
        foreach (var n in list)
        {
            Console.WriteLine(n);
        }
    }

    // Operators that force immediate execution
    public void ImmediateExecutionOperators()
    {
        var numbers = new List<int> { 1, 2, 3, 4, 5 };

        // These execute immediately
        var array = numbers.Where(n => n > 2).ToArray();
        var dict = numbers.ToDictionary(n => n, n => n * 2);
        var hashSet = numbers.

Related in General