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.
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:
relációs adatbázisok
alkalmazás belső objektum készletei (tömb, lista, halmaz,...)
XML adatforrások
ADO DataSet
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:
objektum-forrás kijelölőú rész (from clause, join clause)
szelekiós rész (where clause)
egység kijelölés (let clause)
csoportképzés (groupby clause)
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
A támogatott operátorok körét foglalja össze az alábbi táblázat.
Select : Az eredmény objektum megadását végző operátor, a forrás objektumokból generál kimeneti objektumot.
Where: szelekciós operátor. A megadott kifejezést nem teljesítő objektumok nem kerülnek át az eredménybe.
SelectMany: Az objektumhalmaz elemeit összetettnek tekinti és kibontja egy-egy listába, majd ezen listákat összevonja egy eredő listába.
Sum / Min / Max / Average: a megadott függvényen alapuló aggregációs kifejezések az objektum halmazon
Aggregate: általánosított aggregáció
Join: két objektum kollekció szelekciós joinja
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
Take: az objektum kollekció első megadott számú elemét adja vissza
TakeWhile: az objektum kollekció feltételnek megfelelő elemeit adja vissza
Skip: az objektum kollekció első megadott számú elemét hagyja ki az eredményből
SkipWhile: az objektum kollekció feltételnek megfelelő elemeit hagyja ki az eredményből
OfType: az objektum kollekció megadott típusú elemeit adja vissza
Concat : két objektum kollekció egyesítése
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
Reverse : az objektum kollekcióban az elemek sorendjének megfordítása
GroupBy : Elemek csoportosítása az objektum halmazban
Distinct : Az dupplikálások megszüntetése az objektum halmazban
Union / Intersect / Except: két objektum halmaz közötti halmazműveletek (unió, metszet és különbség)
SequenceEqual: két objektumhalmaz egyezősését vizsgálja
First / FirstOrDefault / Last / LastOrDefault: a halmazból az első vagy utolsó olyan elemet adja vissza,mely teljesítia feltételt
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.
ElementAt : a kollekció megadott pozíciójú elemét adja vissza
Any / All : kvantorok az objektumhalmazon (any: létezik, all: minden). Logikai kifejezés áll mögötte és logikai érétket ad vissza.
Contains: ellenőrzi, hogy a kollekció tartalmaz-e egy megadott elemet
Count: kollekció elemeinek adarbszámát adja vissza
var q =
from v in new[] { 11, 5, 3, 17, 4, 32}
where v < 5
select v;
q.Dump(); 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;
}
}var q = B .Count(); Console.WriteLine(q);
var q = B .Where (t => t.ar > 10) .Count(); Console.WriteLine(q);
var q = B .Where (t => t.ar > 10) .Select (e => e.nev) .OrderBy (e => e); Console.WriteLine(q);
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);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);var q = B .Where (t => t.ar > ( B.Average(e => e.ar) ) ) .Select (t => t.nev); Console.WriteLine(q);
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);