📊 1. Die funktionale LINQ-Pipeline
LINQ (Language Integrated Query) revolutioniert die Datenmanipulation in C#. Statt verschachtelter for- und if-Schleifen nutzt du deklarative Extension-Methoden, die wie eine Fließband-Pipeline zusammengesteckt werden:
──► .OrderByDescending(o => o.TotalAmount)
──► .Select(o => new { o.Customer, o.TotalAmount })
──► .ToList() [Materialisierung im Speicher]
// Beispiel: Umsätze nach Produktkategorie aggregieren
var revenueByCategory = orders
.SelectMany(order => order.Items)
.GroupBy(item => item.Category)
.ToDictionary(
group => group.Key,
group => group.Sum(item => item.Price * item.Quantity)
);
⏳ 2. Deferred Execution vs. Sofortige Materialisierung
Ein zentrales Konzept von LINQ ist die verzögerte Ausführung (Deferred Execution):
Methoden wie Where und Select führen die Abfrage noch nicht aus. Sie erstellen lediglich einen Ausführungsplan. Erst wenn die Sequenz enumeriert wird (z.B. mit ToList(), ToArray(), Sum() oder foreach), fließen die Daten!
Where(...) und Select(...) sind wie das Notieren der Bestellung auf dem Kellnerblock. Es wird noch kein Essen gekocht! Erst wenn der Koch mit ToList() die Zubereitung startet, werden die Zutaten durch die Pfannen gejagt.
📑 3. Cheat-Sheet: Wichtigste LINQ Operatoren
| Operator | Typ | Zweck & Beschreibung |
|---|---|---|
.Where(p) |
Filter | Filtert Elemente anhand eines Prädikats (true/false) |
.Select(f) |
Projektion | Transformiert jedes Element in einen neuen Typ oder Wert |
.SelectMany(f) |
Flattening | Ebnung von verschachtelten Listen (z.B. Liste von Items in Orders) |
.OrderBy[Descending] |
Sortierung | Sortiert Sequenzen auf- oder absteigend (Folgesortierung mit ThenBy) |
.GroupBy(keySelector) |
Gruppierung | Gruppiert Elemente nach gemeinsamen Schlüsseln |
.Skip(n).Take(m) |
Partitionierung | Paginierung: Überspringt n Elemente und nimmt die nächsten m |
.Any() / .All() |
Quantoren | Prüft, ob mindestens ein bzw. alle Elemente eine Bedingung erfüllen |
🎯 Aufgaben & Checkliste in Aufgabe.cs
Wenn du ein IEnumerable<T> mehrfach in einer Methode mit .Count() oder foreach durchläufst, führe am Anfang .ToList() aus, um teure wiederholte Berechnungen oder Datenbankabfragen zu verhindern!