LINQ en C#

  1. Inleiding
  2. LINQ Method syntax
  3. LINQ Declarative syntax
  4. Bladeren
  5. IEnumerator / IEnumerable
  6. Slot
  7. Voorbeeldprogramma
  8. Resultaat

Inleiding

LINQ staat voor Language Integrated Query en is bedoeld als een uniforme query opvraagtaal dat losgelaten kan worden op allerlei gegevensbronnen.

In deze post demonstreren we het één en ander aan de hand van een List<T> collectie, maar de taal is zo generiek dat het ook toegepast kan worden op andere gegevensbronnen zoals SQL Server databases, XML-bestanden en Web Services. LINQ wordt ondersteund door C# en Visual Basic .NET.

De collectie die we gaan gebruiken is een generieke List<T> collectie met GHB automobiel objecten. Voor elk automobiel object wordt vastgelegd van wie de auto is en in welke regio de GHB automobiel terecht is gekomen. We vullen de collectie als volgt:

 List<GHB> lijst = new List<GHB>(){
     new GHB("Sandra's auto #1","Noord"),
     new GHB("Peter's auto  #2","Midden"),
     new GHB("Olga's auto   #3","Zuid"),
     new GHB("Jan's auto    #4","Noord"),
     new GHB("Petra's auto  #5","Midden"),
     new GHB("Dirk's auto   #6","Zuid"),
     new GHB("Piet's auto   #7","Noord"),
     new GHB("Klaas' auto   #8","Midden"),
     new GHB("Mieke's auto  #9","Zuid")
 };

up | down

LINQ Method syntax

We willen weten welke GHB automobielen in regio Noord zijn beland waarbij we alles gesorteerd willen hebben op omschrijving. LINQ kent twee syntax vormen en de LINQ instructie ziet er bij een Method syntax als volgt uit:

// LINQ Method syntax
List<GHB>autosInRegioNoord =
lijst
 .OrderBy(x => x.Omschrijving)
 .Where(x => x.Regio == "Noord")
 .ToList();

// Resultaat 
foreach (GHB ghb in autosInRegioNoord)
{
  Console.WriteLine((ghb.Omschrijving));
}

De LINQ instructie in dit voorbeeld heeft drie operatoren waarvan twee daarvan ( .OrderBy() en .Where() ) lambda expressies hebben. Voor de .ToList operator hebben we geen lambda expressie gebruikt. Een lambda expressie bestaat uit een input en een expressie. De x is in dit voorbeeld een input dat staat voor een GHB object dat aanwezig is in de List<T> lijst collectie. De x.Regio == “Noord”  is de expressie waarin we de input gaan evalueren. De evaluatie heeft in dit voorbeeld betrekking op de regio waarin de GHB automobiel zich bevindt. Resultaat:

Jan's auto    #4
Piet's auto   #7
Sandra's auto #1

up | down

LINQ Declarative syntax

Voor LINQ kan ook een declarative syntax gebruikt worden en die syntax lijkt enigszins op SQL (de Structured Query Language). We selecteren de GHB automobielen die zich in regio Zuid bevinden waarbij gesorteerd wordt op omschrijving:

IEnumerable<GHB> autosInRegioZuid =
           from ghb in lijst
           where ghb.Regio == "Zuid"
           orderby ghb.Omschrijving         
           select ghb;

// Resultaat
foreach (GHB ghb in autosInRegioZuid)
{
  Console.WriteLine((ghb.Omschrijving));
}    

Resultaat:

Dirk's auto   #6
Mieke's auto  #9
Olga's auto   #3

up | down

Bladeren

LINQ kent aardig wat operatoren en we demonstreren hoe we de .Skip() en de .Take() operatoren kunnen gebruiken als we bijvoorbeeld een applicatie willen bouwen die een maximaal aantal records op het scherm wil laten zien.

// browsing
// nummeren vanaf 0, 
// dus 1 is de tweede pagina
int bladzijde = 1; 
int recordsPerPagina = 5;

Console.WriteLine(
"\r\nBrowsing - pagina {0}:",bladzijde + 1);

IEnumerable<GHB> 
pagina =
  from ghb in lijst
  .Skip(bladzijde * recordsPerPagina)
  .Take(recordsPerPagina)
  select ghb;
   
  // Resultaat
  foreach (GHB ghb in pagina)
  {
   Console.WriteLine((ghb.Omschrijving));
  }
 

In dit voorbeeld willen we per keer vijf items tonen. De collectie bestaat uit negen items en als we naar de tweede pagina gaan dan worden de items zes tot en met negen getoond:

Browsing - pagina 2:
Dirk's auto   #6
Piet's auto   #7
Klaas' auto   #8
Mieke's auto  #9

up | down

IEnumerable / IEnumerator

Hebben we het over collecties, dan komen de IEnumerable en de IEnumerator interface op één of andere manier altijd ter sprake. Wat zijn die interfaces en wat hebben die met collecties te maken? We zagen de IEnumerable interface ook al bij de LINQ Declarative syntax.

In C# moet elke collectie de IEnumerable<T> en de IEnumerator<T> interface implementeren. Implementatie van die interfaces is verplicht om itereren (door de collectie bladeren) mogelijk te doen maken. We hoeven de implementatie gelukkig niet zelf te doen. Dat heeft C# al voor ons gedaan en we kunnen de implementatie van de desbetreffende interfaces terug vinden bij de definitie van o.a. de List<T> collectie:

We kunnen dus ook een IEnumerable en een IEnumerator gebruiken om door een collectie te “itereren” want beide interfaces zijn bij alle collecties geïmplementeerd. Voor een List<T> kunnen we de IEnumerable en de IEnumerator als volgt gebruiken:

/*
 * ----------
 * Enumerator
 * ----------
*/
Console.WriteLine(
"\r\nGebruik van de Enumerator:");
IEnumerator 
myEnumerator = lijst.GetEnumerator();
while(myEnumerator.MoveNext())
{
  // Boxen..
  GHB ghb = (GHB)myEnumerator.Current;
  Console.WriteLine(ghb.Omschrijving);
}
/*
 * ----------
 * Enumerable
 * ----------
*/
Console.WriteLine(
"\r\nGebruik van deEnumerable:");
IEnumerable myEnumerable = lijst;
foreach (GHB ghb in myEnumerable) {
   Console.WriteLine(ghb.Omschrijving);
}

En we zien wederom de inhoud van de collectie, maar nu met de IEnumerator en de IEnumerable:

Gebruik van de Enumerator:
Sandra's auto #1
Peter's auto  #2
Olga's auto   #3
Jan's auto    #4
Petra's auto  #5
Dirk's auto   #6
Piet's auto   #7
Klaas' auto   #8
Mieke's auto  #9

Gebruik van de Enumerable:
Sandra's auto #1
Peter's auto  #2
Olga's auto   #3
Jan's auto    #4
Petra's auto  #5
Dirk's auto   #6
Piet's auto   #7
Klaas' auto   #8
Mieke's auto  #9

up | down

Slot

LINQ staat voor Language Integrated Query en in deze post heb ik laten zien hoe we met LINQ gegevens uit een collectie kunnen opvragen. Ik heb me in de voorbeelden beperkt tot een selectie en een sortering (met de .OrderBy() en de .Where() operatoren), maar LINQ kent nog veel meer operatoren. Zo heb ik laten zien hoe je de .Skip() en de .Take() operatoren kunt gebruiken voor het doen maken van een applicatie waarbij je door een collectie heen wilt bladeren en een maximaal aantal records per keer op het scherm getoond moeten worden.

LINQ kent qua syntax twee smaken, de Method syntax en de Declarative syntax. De Declarative syntax lijkt enigszins op SQL (de Structured Query Language) en deze syntax zal waarschijnlijk erg prettig zijn voor de mensen die SQL niet los kunnen laten.

In C# moet elke collectie de IEnumerable en de IEnumerator interface implementeren. Implementatie van die interfaces is verplicht om itereren (door de collectie bladeren) mogelijk te doen maken. Ik heb laten zien dat je met een IEnumerable en een IEnumerator ook door een collectie kunt “itereren”.

Hopelijk ben je met deze posting weer wat wijzer geworden en ik hoop je weer terug te zien in één van mijn volgende blog posts. Wil je weten wat ik nog meer over C# heb geschreven? Hit the C# button…

up | down


Voorbeeldprogramma

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

namespace Voorbeelden
{
  public class GHB
  {
    //Backing variables - fields --
    private string _omschrijving;
    private string _regio;
    
    public GHB(string omschrijving, string regio)
    {
      _omschrijving = omschrijving;
      _regio = regio;
    }
    
    public string Omschrijving
    {
      get { return _omschrijving; }
      set { _omschrijving = value; }
    }
    
    public string Regio
    {
      get { return _regio; }
      set { _regio = value; }
    }
  }
  
  class MainClass
  {
     public static void Main(string[] args)
     {
       /*
       * -----------
       * List vullen 
       * -----------
       */
       List<GHB> lijst = new List<GHB>(){
           new GHB("Sandra's auto #1","Noord"),
           new GHB("Peter's auto  #2","Midden"),
           new GHB("Olga's auto   #3","Zuid"),
           new GHB("Jan's auto    #4","Noord"),
           new GHB("Petra's auto  #5","Midden"),
           new GHB("Dirk's auto   #6","Zuid"),
           new GHB("Piet's auto   #7","Noord"),
           new GHB("Klaas' auto   #8","Midden"),
           new GHB("Mieke's auto  #9","Zuid")
       };
       /* 
        * -------------
        * Method Syntax
        * -------------
       */
       Console.WriteLine(
       "De GHB automobielen uit regio Noord:");
       List<GHB>autosInRegioNoord =
       lijst
         .OrderBy(x => x.Omschrijving)
         .Where(x => x.Regio == "Noord")
         .ToList();
       // Resultaat 
       foreach (GHB ghb in autosInRegioNoord)
       {
         Console.WriteLine((ghb.Omschrijving));
       }
       /*
        * ------------------------
        * Declarative query syntax
        * ------------------------
       */
       Console.WriteLine(
       "\r\nDe GHB automobielen uit regio Zuid:");
       IEnumerable<GHB> autosInRegioZuid =
           from ghb in lijst
           where ghb.Regio == "Zuid"
           orderby ghb.Omschrijving         
           select ghb;
       // Resultaat
       foreach (GHB ghb in autosInRegioZuid)
       {
        Console.WriteLine((ghb.Omschrijving));
       }    
       /*
        * --------
        * browsing
        * nummeren vanaf 0, 
        * dus 1 is de tweede pagina
        * --------
       */
       int bladzijde = 1; 
       int recordsPerPagina = 5;
       Console.WriteLine(
       "\r\nBrowsing - pagina {0}:",bladzijde + 1);
       IEnumerable<GHB> 
         pagina =
         from ghb in lijst
         .Skip(bladzijde * recordsPerPagina)
         .Take(recordsPerPagina)
         select ghb;
       // Resultaat
       foreach (GHB ghb in pagina)
       {
         Console.WriteLine((ghb.Omschrijving));
       }
       /*
        * ----------
        * Enumerator
        * ----------
       */
       Console.WriteLine(
       "\r\nGebruik van de Enumerator:");
      IEnumerator 
      myEnumerator = lijst.GetEnumerator();
      while(myEnumerator.MoveNext())
      {
        // Boxen..
        GHB ghb = (GHB)myEnumerator.Current;
        Console.WriteLine(ghb.Omschrijving);
      }
      /*
       * ----------
       * Enumerable
       * ----------
      */
      Console.WriteLine(
      "\r\nGebruik van de Enumerable:");
      IEnumerable myEnumerable = lijst;
      foreach (GHB ghb in myEnumerable) {
         Console.WriteLine(ghb.Omschrijving);
      }
    }
  }
}

up | down

Resultaat

De GHB automobielen uit regio Noord:
Jan's auto    #4
Piet's auto   #7
Sandra's auto #1

De GHB automobielen uit regio Zuid:
Dirk's auto   #6
Mieke's auto  #9
Olga's auto   #3

Browsing - pagina 2:
Dirk's auto   #6
Piet's auto   #7
Klaas' auto   #8
Mieke's auto  #9

Gebruik van de Enumerator:
Sandra's auto #1
Peter's auto  #2
Olga's auto   #3
Jan's auto    #4
Petra's auto  #5
Dirk's auto   #6
Piet's auto   #7
Klaas' auto   #8
Mieke's auto  #9

Gebruik van de Enumerable:
Sandra's auto #1
Peter's auto  #2
Olga's auto   #3
Jan's auto    #4
Petra's auto  #5
Dirk's auto   #6
Piet's auto   #7
Klaas' auto   #8
Mieke's auto  #9

up

Laat een reactie achter

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *