2.9. LINQ

2.9.1. Működési környezet

2.9.1.1. Sorolja fel a LINQ rendszer főbb jellemzőit!

A LINQ célja egy univerzális objektum-halmaz lekérdező API felület biztosítása, mely révén bármilyen objektum forrásból egységes szintaktikával lehet az igényelt objektumokat begyűjteni. A LINQ kifejezések szintaktikája több elemében az SQL szintaktikájára épít,de számos ponton el is tér tőle. A lekérdezésekben az SQL mellett számos xQuery vonást is felfedezhetünk, ami összecseng azzal a törekvéssel, hogy a LINQ-t az XML adatokra is alkalmazható felületet biztosít.

A LINQ rendszer fő jellemzője az egységes lekérdező felület mellett az, hogy a lekérdezés gazdanyelvi szinten valósul meg, tehát a parancs végrehajtása nem a távoli DBMS magjában fut le, hanem az alkalmazásban. Ennek előnye, hogy a lekérdezés közvetlenül nyomkövethető, a hibakezelés a gazdanyelvi környezetbe integrálható. A LINQ API mögött tehát egy a gazdanyelve ágyazott mini DBMS motor működiik, mely az alkalmazás saját adatival dolgozhat. Ez a működési mód természetesen nem alkalmazható elosztottan módosítható adatok esetében, ott továbbra is centralizált DBMS viztisítja a megoldást.

2.9.1.2. Milyen adatforrásokat támogat a LINQ rendszer?

A LINQ rendszer egy olyan API adatlekérdező felület amely az adatforrások széles körét támogatva halmaz orientált lekérdező kifejezések használatát teszi lehetvé. A LINQ által támogatott adatforrások:

  1. relációs adatbázisok

  2. alkalmazás belső objektum készletei (tömb, lista, halmaz,...)

  3. XML adatforrások

  4. ADO DataSet

2.9.1.3. Adja meg a LINQ lekérdezés általános alakját!

A LINQ lekérdezés általános alakja az alábbi absztrakt szintaktikára illeszkedik:

   Q = from-clause join-clause*
   (from-clause join-clause* | let-clause | where-clause)*
   (orderby-clause)?
   (select-clause | groupby-clause)
   (query-continuation Q) ?
      

A LINQ lekérdezés tehát az alábbi komponenseket tartalmazhatja:

  1. objektum-forrás kijelölőú rész (from clause, join clause)

  2. szelekiós rész (where clause)

  3. egység kijelölés (let clause)

  4. csoportképzés (groupby clause)

  5. rendezés (oorderby clause)

A lekérdezések egymásba ágyazhatók és egymásután f0zhetők. Az egyes query elemek halmazműveletekkel összefűzhetők

2.9.1.4. Milyen adatkezelő operátorokat támogat a LINQ rendszer?

A támogatott operátorok körét foglalja össze az alábbi táblázat.

  1. Select : Az eredmény objektum megadását végző operátor, a forrás objektumokból generál kimeneti objektumot.

  2. Where: szelekciós operátor. A megadott kifejezést nem teljesítő objektumok nem kerülnek át az eredménybe.

  3. SelectMany: Az objektumhalmaz elemeit összetettnek tekinti és kibontja egy-egy listába, majd ezen listákat összevonja egy eredő listába.

  4. Sum / Min / Max / Average: a megadott függvényen alapuló aggregációs kifejezések az objektum halmazon

  5. Aggregate: általánosított aggregáció

  6. Join: két objektum kollekció szelekciós joinja

  7. GroupJoin: két objektum kollekció csoport szelekciós join művelete. Ekkor a az alap Jointól eltérően nem objekum párokat képez, hanem objektum csoportok párjait lehet megadni

  8. Take: az objektum kollekció első megadott számú elemét adja vissza

  9. TakeWhile: az objektum kollekció feltételnek megfelelő elemeit adja vissza

  10. Skip: az objektum kollekció első megadott számú elemét hagyja ki az eredményből

  11. SkipWhile: az objektum kollekció feltételnek megfelelő elemeit hagyja ki az eredményből

  12. OfType: az objektum kollekció megadott típusú elemeit adja vissza

  13. Concat : két objektum kollekció egyesítése

  14. OrderBy / ThenBy : objektum kollekció rendezése, az OrderBy az elsődleges rendezési szempontot adja meg, míg a Thenby a másodlagos rendezési kulcsot jelöli ki

  15. Reverse : az objektum kollekcióban az elemek sorendjének megfordítása

  16. GroupBy : Elemek csoportosítása az objektum halmazban

  17. Distinct : Az dupplikálások megszüntetése az objektum halmazban

  18. Union / Intersect / Except: két objektum halmaz közötti halmazműveletek (unió, metszet és különbség)

  19. SequenceEqual: két objektumhalmaz egyezősését vizsgálja

  20. First / FirstOrDefault / Last / LastOrDefault: a halmazból az első vagy utolsó olyan elemet adja vissza,mely teljesítia feltételt

  21. Single: Egy olyan elemet ad vissza,mely teljesítia megadott feltételt. A következő híváskor a soronkövetkező ilyen elemet adja meg.

  22. ElementAt : a kollekció megadott pozíciójú elemét adja vissza

  23. Any / All : kvantorok az objektumhalmazon (any: létezik, all: minden). Logikai kifejezés áll mögötte és logikai érétket ad vissza.

  24. Contains: ellenőrzi, hogy a kollekció tartalmaz-e egy megadott elemet

  25. Count: kollekció elemeinek adarbszámát adja vissza

2.9.2. Mintaparancsok

2.9.2.1. Egy adott számsorozatból az 5-nél kisebb értékűeket irassuk ki, használjunk deklaratív parancsmódot.

var q =
      from v in new[] { 11, 5, 3, 17, 4, 32}
         where v < 5
      select v;
   q.Dump();

2.9.2.2. Készítsen egy szelekciós joint terméknév - gyártónév párosok listájára. A terméket egy (gyártó, név, ár) a gyártót (kód, név) adatok jellemeznek. Használjon deklaratív parancsalakot

   void Main()
   {
      Tgyarto[] A = new Tgyarto[2];
      Ttermek[] B = new Ttermek[5];
      A[0] = new Tgyarto(1,"VASGYAR");
      A[1] = new Tgyarto(2,"ITALGYAR");
      B[0] = new Ttermek(1,"KAPA",23);
      B[1] = new Ttermek(1,"ASO",15);
      B[2] = new Ttermek(2,"TEJ",8);
      B[3] = new Ttermek(2,"VODKA",13);
      B[4] = new Ttermek(2,"TRAUBI",6);
   
      var q =
        from a in A
        join b in B on a.kod equals b.gyarto
        select new {anev = a.nev, bnev = b.nev};
   
      foreach (var v in q) {
        Console.WriteLine(v.anev+" "+ v.bnev);
      }
   }
   
   class Tgyarto {
      public int kod;
      public String nev;
   
      public Tgyarto (int a, String b) {
         this.kod = a;
                this.nev = b;
      }
   }
   
   class Ttermek {
      public int gyarto;
      public String nev;
      public int ar;
   
      public Ttermek (int a, String b, int c) {
         this.gyarto = a;
         this.nev = b;
         this.ar = c;
      }
   }

2.9.2.3. Irassa ki a termékek darabszámát. Használjon funkcionális parancsalakot..

var q = B
      .Count();
         Console.WriteLine(q);

2.9.2.4. Irassa ki a 10-nél drágább ermékek darabszámát. Használjon funkcionális parancsalakot.

var q = B
      .Where (t => t.ar > 10)
      .Count();
   Console.WriteLine(q);

2.9.2.5. Irassa ki a 10-nél drágább termékek neveit ABC sorrendben, funkcionális parancsalakban.

var q = B
      .Where (t => t.ar > 10)
      .Select (e => e.nev)
      .OrderBy (e => e);
   Console.WriteLine(q);

2.9.2.6. Irassi ki az ITALGYAR termékeit, funkcionális alakot használjon. A nevek rendezve jelenjenek meg.

var q = A
      .Where (t => t.nev == "ITALGYAR")
      .Join(B, b => b.kod, a => a.gyarto, (a,b) => new {b.nev})
      .OrderBy(e => e.nev);
   Console.WriteLine(q);

2.9.2.7. Irassi ki az ITALGYAR termékeinek átlagárát, funkcionális alakot használjon.

var q = A
   .Where (t => t.nev == "ITALGYAR")
   .Join(B, b => b.kod, a => a.gyarto, (a,b) => new {b.nev, b.ar})
   .Average(e => e.ar);
   Console.WriteLine(q);

2.9.2.8. Listázza ki az átlagárnál drágább termékek neveit, funkcionális kódot alkalmazzon.

var q = B
      .Where (t => t.ar > ( B.Average(e => e.ar) ) )
      .Select (t => t.nev);
   Console.WriteLine(q);

2.9.2.9. Kérdezze le az italgyári termékek átlagáránál drágább termékek neveit ABC sorrendben, funkcionális parancsalakban.

var q = B
      .Where (t => t.ar > ( A
      .Where (e => e.nev == "ITALGYAR")
      .Join(B, b => b.kod, a => a.gyarto, (a,b) => new {b.nev, b.ar})
      .Average(e => e.ar) ) )
      .Select (t => t.nev)
      .OrderBy (t => t);
   Console.WriteLine(q);