avatar
Today is Friday
October 18, 2019

May 8, 2007

(D)LINQ

by tsnoei — Categories: Uncategorized — 1 Comment - Afdrukken Afdrukken

LINQ.pngNa de installatie van VS Orcas (de opvolger van Visual Studio 2005) een tijdje geleden alweer, ben ik eindelijk eens met Orcas gaan stoeien. M’n laptop had het overigens wel zwaar met het draaien van 2 operating systemen tegelijkertijd. Orcas draait namelijk onder Microsoft Virtual PC met Windows 2003 operating systeem. Mijn laptop is uitgerust met 1 Gb geheugen maar toch is mijn systeem dan continue aan het swappen. Is Orcas in de lucht dan duld mijn OS geen enkele andere RAM-vretende applicatie zoals Outlook of Onenote. Dit heeft me een tijdje weerhouden van het onderzoeken van LINQ maar ik ben nu toch maar aan de slag gegaan. Met het vooruitzicht van een geheugenuitbreiding van een halve Gig (bedankt baas) wil ik nu wel even in de wacht staan.

Een leuke nieuwe feature in Orcas is onder andere ondersteuning van de LINQ syntax. LINQ staat voor Language INtegrated Query en voorziet in de mogelijkheid met SQL-achtige queries binnen je code data te verzamelen uit bijvoorbeeld collections. De scheidslijn tussen database data en object data wordt hierdoor een stuk kleiner.

Om te beginnen heb ik binnen Orcas een Console applicatie aangemaakt. In de main functie van Program.cs heb ik de volgende code geschreven:

string[] names = new string[] { "Jan", "Piet", "Bob", "Klaas", "Koos" };
IEnumerable result = from n in names where n.Length <= 4 orderby n select n;
foreach (string res in result)
   Console.WriteLine(res);

Console.WriteLine("Press a key");

In deze code wordt een string array gecreeerd met namen. De LINQ query, op regel 2, is van het type IEnumerable en verzamelt alle namen met een lengte van maximaal 4 karakters en sorteert daarnaast de namen op alfabet. In de foreach lus worden de namen naar de console geschreven. Het resultaat is dus dit:

Console1.JPG

Lazy loading?
Wat belangrijk is om te weten is dat op de 2e regel waarbij de LINQ query wordt toegewezen aan de variabele IEnumerable “result” niet het resultaat wordt vastgelegd maar enkel de query definitie. Als op de 3e regel daadwerkelijk in de foreach loop van de IEnumerable de items op worden gevraagd, dan wordt pas daadwerkelijk de selectie van de data uitgevoerd. In dit geval is het om het even. Maar gaan we gebruiken maken van een database voor het ophalen van data via een DLINQ query dan is dit weldegelijk een relevant gegeven! We hebben het hier dus over mix tussen normale en lazy loading.

Meer voorbeelden van LINQ queries kan je vinden op de “101 LINQ samples” pagina van Microsoft.

Nu wat meer over DLINQ en laat je verbazen. LINQ op zich geeft mij al een WOW! gevoel, maar DLINQ is echt WOW! in het kwadraat. Het stappenplan:

  1. Ga gewoon verder in dezelfde console applicatie
  2. Aangezien op de Virtual PC image ook SQL Server is geinstalleerd, creeer een database.
  3. Creeer 2 tabellen in de database 1 met de naam “Medewerker” en een andere met de naam “Bedrijf”.
  4. Voeg de volgenden velden toe aan de tabel “Medewerker”: Id (int), Voornaam, Achternaam, BedrijfId (int).
  5. Medewerker.JPG

  6. Voeg de volgenden velden toe aan de tabel “Bedrijf”: Id (int), Naam.
  7. Bedrijf.JPG

  8. De Id velden in beide tabellen zijn van het type Identity.
  9. Leg een Foreign key relatie van Medewerker.BedrijfId naar Bedrijf.Id.
  10. Relationship.JPG

  11. Nu kiezen we voor ons console project Add > New Item > LINQ To SQL File. We noemen de file Bedrijfsdata.dbml.
  12. DBMLDialog.JPG

  13. Bedrijfsdata.dbml wordt nu getoond. We slepen nu vanuit de “Server Explorer” de tabellen op de dbml.
  14. DBMLBedrijfsdata.JPG

  15. We hebben nu een koppeling gecreeerd met een database die we kunnen gebruiken binnen LINQ. We kunnen nu code gaan kloppen.

Binnen het project is nu de class BedrijfsdataDataContext beschikbaar waarmee we de database kunnen benaderen. Met de volgende code voegen we een bedrijf toe aan de database:

//Creer een nieuwe datacontext
BedrijfsdataDataContext dc = new BedrijfsdataDataContext();
//Creeer een Bedrijf (is automatisch beschikbaar via Context)
Bedrijf b = new Bedrijf();
//Vul de properties
b.Naam = "Conclusion Core Technologies";
//Voeg het bedrijf toe in de context
//Door engelse context wordt lijst met bedrijven "Bedrijfs" genoemd
dc.Bedrijfs.Add(b);
//Sla alle wijzigingen in de context op in de database
dc.SubmitChanges();

Console.WriteLine("Press a key...");

Medewerkers kunnen als volgt aan dit bedrijf worden toegevoegd:

BedrijfsdataDataContext dc = new BedrijfsdataDataContext();
Medewerker m = new Medewerker();
m.Voornaam = "Ton";
m.Achternaam = "Snoei";
m.Bedrijf = (from b in dc.Bedrijfs where
  b.Naam.StartsWith("Conclusion") select b).First();
dc.Medewerkers.Add(m);
dc.SubmitChanges();
Console.WriteLine("Press a key...");

Het leuke is dat voor elke willekeurige medewerker het bedrijfobject kan worden opgevraagd of voor elk bedrijf een lijst met alle medewerkers. Zoals eerder gezegd, het bedrijf object bevat dan wel een property van het type IEnumerable met de naam Medewerkers, dat wil echter niet zeggen dat zich hier een gevulde collectie met medewerkers bevindt. Deze property bevat een definitie om alle medewerkers van het betreffende bedrijf op te halen. Zolang echter niets met de medewerkers property wordt gedaan worden deze dus ook niet uit de database opgehaald. De optimale manier van lazy loading!!

Het is jammer voor teams als die van NHibernate die jaren hebben besteedt aan het bouwen van een mooie oplossing om objecten van en naar een database te “mappen”. Denk eens aan mijn mooie mapper die kan ook de kast in ;-) . Maar een betere object relational mapper als DLINQ ben ik nog niet tegengekomen. Dit komt natuurlijk mede door het feit dat Microsoft vrij is om de syntax van een ontwikkeltaal aan te passen. Daarnaast is het concept natuurlijk ook goed doordacht. Er is wel 1 nadeel, DLINQ werkt vooralsnog alleen met SQL Server.

Ik zou zeggen experimenteer er zelfs een mee. Leuk is ook om de SQL Profiler er bij te pakken om eens te kijken hoe de LINQ queries zich verhouden met SQL. Ik heb zelf ervaren dat dit heel leerzaam is. Voor degene die ook al een blik hebben geworpen op WPF is het duidelijk dat het koppelen van data op alle vlakken gemakkelijker is geworden.

Kortom, ik denk dat we hier met zijn alle heel veel profijt van gaan hebben. Ik kan niet wachten tot de officiele release uit is van Orcas en kan elk bedrijf dan ook aanraden direct over te stappen op dit nieuwe concept. Er valt heel wat geld te besparen, want over het algemeen slokt een datalaag toch een redelijk deel van een ontwikkelbudget op van een willekeurig project.

Facebook comments:

1 Comment »

  1. frederik says:

    NHibernate ed zullen zeker niet ‘in de kast’ vliegen, aangezien LINQ for Entities zeker nog zo ver niet staat als NHibernate bv.
    Daarbij zullen projecten die momenteel in NHibernate gemaakt worden, ook niet echt herschreven worden om LINQ for entities te gaan gebruiken.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

© 2019 Snoei's .NET blog All rights reserved - Wallow theme v0.44 by ([][]) TwoBeers - Powered by WordPress - Have fun!