LINQ Note

2024-07-01

筆記 LINQ 的使用方式。

logo

說明

為什麼我們不需要使用 system.Linq 來使用 Linq?因為 .NET 專案預設透過 ImplicitUsing,已經將 System.Linq 命名空間隱含的加入專案中。

在 Linq (Language Integrated Query) 中,有兩種主要的語法 (syntaxes) 來撰寫查詢,Query Syntax 和 Method Syntax。

Query Syntax

Query Syntax 使用類似 SQL 的語法來撰寫查詢,但有些操作無法使用 Query Syntax 來達成。

var query =
    from student in students
    where student.Age > 20
    orderby student.LastName ascending
    select student.FirstName;

Method Syntax:

Method Syntax 使用 fluent API 的方式來撰寫查詢,能夠支援所有的查詢操作。

var query = students
    .Where(student => student.Age > 20)
    .OrderBy(student => student.LastName)
    .Select(student => student.FirstName);

Groupby in Linq

// Linq how to group by example

var names = new string[] { "Alice", "Allen", "Bob", "Cindy", "Cathy" };

// Method Syntax
var query = names.GroupBy(name => name[0])
                 .Select(g => new { FirstLetter = g.Key, Names = g });

// Query Syntax
query = from name in names
            group name by name[0] into g
            select new { FirstLetter = g.Key, Names = g };


foreach (var group in query)
{
    Console.WriteLine(group.FirstLetter);
    foreach (var name in group.Names)
    {
        Console.WriteLine("  " + name);
    }
}

Advanced Groupby in Linq Example

// Category for game products
List<Category> categories = [
    new Category(1, "Action"),
    new Category(2, "Adventure"),
    new Category(3, "RPG"),
    new Category(4, "Simulation"),
    new Category(5, "Strategy")
];

// Game Products
List<Product> products = [
    new(1, "GTA V", 29.99m, categories[0]),
    new(2, "The Witcher 3", 19.99m, categories[2]),
    new(3, "Cyberpunk 2077", 49.99m, categories[2]),
    new(4, "FIFA 22", 59.99m, categories[0]),
    new(5, "Assassin's Creed Valhalla", 39.99m, categories[1]),
    new(6, "Civilization VI", 29.99m, categories[4])
];

var query = from p in products
            group p by p.Category.Name;

foreach (var g in query)
{
    Console.WriteLine(g.Key);
    foreach (var p in g)
    {
        Console.WriteLine($"  {p.Name} - {p.Price}");
    }
    Console.WriteLine();
}


record Category(int CategoryId, string Name);
record Product(int ProductId, string Name, decimal Price, Category Category);

Group Values by Key in Linq

var query = from p in products
            group p by p.Category.Name into g
            where g.Count() >= 2
            select g;

What difference between groupby and tolookup in linq

Key Differences Summary:

  • Return Type: GroupBy returns IEnumerable<IGrouping<TKey, TElement>>, while ToLookup returns ILookup<TKey, TElement>.
  • Execution: GroupBy uses deferred execution, ToLookup executes immediately.
  • Indexing: ToLookup allows indexed access to groups by key efficiently.

Choosing Between GroupBy and ToLookup:

  • Use GroupBy when you need deferred execution or plan to perform further aggregation or operations on each group.
  • Use ToLookup when you need immediate execution and efficient keyed access to groups.

OfType in Linq

OfType is able to filter the collection by a specific type.

Account[] accounts = [
    new SavingsAccount(1, "Savings Account 1"),
    new SavingsAccount(2, "Savings Account 2"),
    new CreditCardAccount(3, "Credit Card Account 1"),
    new CreditCardAccount(4, "Credit Card Account 2")
];

var result = accounts.OfType<SavingsAccount>();

foreach (var item in result)
{
    Console.WriteLine((item.AccountId, item.Name));
}


record Account(int AccountId, string Name);
record SavingsAccount(int AccountId, string Name): Account(AccountId, Name);
record CreditCardAccount(int AccountId, string Name): Account(AccountId, Name);