LINQ Query Syntax is SQL-achtige manier om gegevens te bevragen in C#. Het biedt een gestructureerde manier om collecties, databases en andere gegevensbronnen te filteren, sorteren en transformeren.
Hoe zit LINQ query syntax in elkaar?
LINQ (Language Integrated Query) biedt een query-gebaseerde manier om data te filteren, groeperen en transformeren binnen C#. Query Syntax is een van de twee manieren om LINQ te schrijven en lijkt sterk op SQL.
Bij LINQ Query Syntax gebruik je keywords zoals from, where, select en orderby om gegevens uit een bron (zoals een lijst of database) op te vragen. De basisstructuur ziet er als volgt uit:
var resultaat = from <element> in <bron> where <voorwaarde> select <element>;
Dit bestaat uit:
from Bepaalt de bron en de naam van het element (bijv. n in numbers).
where Filtert de data op basis van een voorwaarde.
select Geeft aan wat je als resultaat wilt krijgen.
Codevoorbeeld
Laten we een lijst van getallen nemen en alleen de even getallen selecteren.
int[] numbers = { 1, 2, 3, 4, 5, 6 };// LINQ Query Syntaxvar evenNumbers = from n in numbers where n % 2 == 0 select n;
Uitleg codevoorbeeld
from n in numbers → Loop door elk element n in de lijst numbers.
where n % 2 == 0 → Houd alleen de even getallen over.
select n → Selecteer de overgebleven waarden als eindresultaat.
Wanneer je dit uitvoert, bevat evenNumbers de waarden { 2, 4, 6 }.
Casus Declaratief vs. Imperatief Programmeren
Bij het ontwikkelen van een applicatie komt een programmeur voor de keuze tussen twee programmeerstijlen: declaratief en imperatief. Deze keuze heeft invloed op de leesbaarheid, onderhoudbaarheid en efficiëntie van de code.
De situatie
Een ontwikkelaar krijgt de taak om alle even getallen uit een lijst te filteren. Dit kan op twee manieren:
Declaratieve aanpak
De programmeur schrijft een query die beschrijft wat er moet gebeuren, zonder de details van de uitvoering te specificeren:
var evenNumbers = from n in numbers where n % 2 == 0 select n;
Hier wordt simpelweg aangegeven: “Selecteer alle even getallen uit de lijst.” Hoe dit precies gebeurt, wordt overgelaten aan de LINQ-engine van C#.
Imperatieve aanpak
De programmeur kiest een meer stapsgewijze benadering en bepaalt zelf hoe de taak uitgevoerd moet worden:
List<int> evenNumbers = new List<int>(); foreach (var n in numbers) { if (n % 2 == 0) { evenNumbers.Add(n); } }
Hier wordt elke stap handmatig gedefinieerd:
Een lege lijst aanmaken.
Door elk getal in de lijst itereren.
Controleren of het even is.
Het getal toevoegen aan de nieuwe lijst.
Analyse
De declaratieve aanpak is korter en leesbaarder, terwijl de imperatieve aanpak meer controle biedt, maar omslachtiger is. In moderne softwareontwikkeling wordt vaak de declaratieve stijl geprefereerd vanwege de eenvoud en efficiëntie.
Welke aanpak zou jij kiezen voor je volgende project?
Hoe gebruik je LINQ query syntax?
Je kunt LINQ query syntax goed gebruiken als:
je SQL-achtige leesbare query wilt schrijven.
je te maken hebt met complexe bevragingen zoals group by of join.
je samenwerkt met databases (bijv. Entity Framework).
Sorteren met orderby
LINQ Query Syntax kan ook data sorteren met orderby.
var sortedNumbers = from n in numbers orderby n descending select n;
Hiermee sorteer je numbersaflopend. Zonder descending zou het oplopend sorteren.
Codevoorbeeld
var numbers = new List<int> { 1, 2, 3, 4, 5, 6 };var evenNumbers = from num in numbers where num % 2 == 0 orderby num descending select num;foreach (var n in evenNumbers){ Console.WriteLine(n); // Output: 2, 4, 6}
Groeperen met group by in LINQ Query Syntax
Met group by kun je gegevens groeperen op basis van een bepaalde eigenschap, net zoals in SQL. De algemene structuur is:
var resultaat = from <element> in <bron> group <element> by <kenmerk> into <groepsnaam> select <groepsnaam>;
Codevoorbeeld: Groeperen van namen op basis van hun eerste letter
string[] namen = { "Anna", "Arjen", "Bart", "Bram", "Cindy" };var groepen = from naam in namen group naam by naam[0] into naamGroep select naamGroep;
Uitleg codevoorbeeld
group naam by naam[0] → groepeert de namen op de eerste letter.
into naamGroep → geeft de groep een naam.
select naamGroep → retourneert de groepen.
Uitvoer:
Groep ‘A’: { “Anna”, “Arjen” }
Groep ‘B’: { “Bart”, “Bram” }
Groep ‘C’: { “Cindy” }
Joinen van lijsten met join in LINQ Query Syntax
Met join kun je gegevens uit twee verzamelingen combineren op basis van een gemeenschappelijke eigenschap. Dit werkt zoals een INNER JOIN in SQL.
var resultaat = from <element1> in <bron1> join <element2> in <bron2> on <element1.eigenschap> equals <element2.eigenschap> select <gecombineerdResultaat>;
Codevoorbeeld Orders koppelen aan klanten
var klanten = new[]{ new { Id = 1, Naam = "Alice" }, new { Id = 2, Naam = "Bob" }};var orders = new[]{ new { KlantId = 1, Product = "Laptop" }, new { KlantId = 2, Product = "Telefoon" }};var klantOrders = from k in klanten join o in orders on k.Id equals o.KlantId select new { k.Naam, o.Product };
Uitleg Codevoorbeeld
from k in klanten → Selecteert alle klanten.
join o in orders on k.Id equals o.KlantId → Combineert klanten met hun bestellingen.
select new { k.Naam, o.Product } → Haalt de relevante gegevens op.
Anoniem object
Opvallend is het gebruik van het keyword new zonder klasse. Dit is een anoniem object. Dit wordt veel gebruikt bij LINQ.
Uitvoer:
Alice → Laptop
Bob → Telefoon
Left Join en Multiple Joins in LINQ Query Syntax
Een left join zorgt ervoor dat alle elementen uit de linker verzameling behouden blijven, zelfs als er geen overeenkomstige elementen in de rechter verzameling zijn.
Bij multiple joins koppel je gegevens uit meerdere verzamelingen. Dit kan handig zijn bij complexe relaties, zoals een koppeling tussen klanten, orders en producten.
Left Join in LINQ Query Syntax
C# ondersteunt geen left join direct in query syntax zoals in SQL. Maar je kunt dit simuleren met DefaultIfEmpty(), waardoor ontbrekende waarden worden opgevuld met null.
Codevoorbeeld Klanten en hun bestellingen (met klanten zonder orders)
var klanten = new[]{ new { Id = 1, Naam = "Alice" }, new { Id = 2, Naam = "Bob" }, new { Id = 3, Naam = "Charlie" } // Heeft geen order};var orders = new[]{ new { KlantId = 1, Product = "Laptop" }, new { KlantId = 2, Product = "Telefoon" }};var klantOrders = from k in klanten join o in orders on k.Id equals o.KlantId into klantGroep from order in klantGroep.DefaultIfEmpty() // Left Join simulatie select new { k.Naam, Product = order?.Product ?? "Geen bestelling" };foreach (var item in klantOrders){ Console.WriteLine($"{item.Naam} - {item.Product}");}
Uitleg codevoorbeeld
join o in orders on k.Id equals o.KlantId into klantGroep Groepeert orders per klant.
from order in klantGroep.DefaultIfEmpty() Zorgt ervoor dat klanten zonder orders ook worden opgenomen (met null als er geen order is).
order?.Product ?? "Geen bestelling" Vervangt null door "Geen bestelling".
Uitvoer:
Alice - Laptop
Bob - Telefoon
Charlie - Geen bestelling
Multiple Joins in LINQ Query Syntax
Met multiple joins kun je gegevens uit meerdere tabellen combineren.
Codevoorbeeld: Klanten, Orders en Producten
var klanten = new[]{ new { Id = 1, Naam = "Alice" }, new { Id = 2, Naam = "Bob" }};var orders = new[]{ new { KlantId = 1, OrderId = 101 }, new { KlantId = 2, OrderId = 102 }};var producten = new[]{ new { OrderId = 101, Product = "Laptop" }, new { OrderId = 102, Product = "Telefoon" }};var klantOrders = from k in klanten join o in orders on k.Id equals o.KlantId join p in producten on o.OrderId equals p.OrderId select new { k.Naam, p.Product };foreach (var item in klantOrders){ Console.WriteLine($"{item.Naam} - {item.Product}");}
Uitleg codevoorbeeld
join o in orders on k.Id equals o.KlantId Koppelt klanten aan orders.
join p in producten on o.OrderId equals p.OrderId Koppelt orders aan producten.
select new { k.Naam, p.Product } Haalt de relevante gegevens op.