Megosztás a következőn keresztül:


Az első LINQ-lekérdezés írása (Visual Basic)

A lekérdezési olyan kifejezés, amely adatokat kér le egy adatforrásból. A lekérdezések dedikált lekérdezési nyelven vannak kifejezve. Idővel különböző nyelveket fejlesztettek ki különböző típusú adatforrásokhoz, például a relációs adatbázisokhoz készült SQL-hez és az XML-hez készült XQueryhez. Ez szükségessé teszi, hogy az alkalmazásfejlesztő új lekérdezési nyelvet tanuljon minden támogatott adatforrás- vagy adatformátumhoz.

Language-Integrated Lekérdezés (LINQ) leegyszerűsíti a helyzetet azáltal, hogy konzisztens modellt kínál az adatok különböző adatforrások és formátumok közötti használatához. A LINQ-lekérdezésekben mindig objektumokkal dolgozik. Ugyanezekkel az alapszintű kódolási mintákkal kérdezheti le és alakíthatja át az adatokat XML-dokumentumokban, SQL-adatbázisokban, ADO.NET adathalmazokban és entitásokban, .NET-keretrendszer-gyűjteményekben és bármely más forrásban vagy formátumban, amelyhez egy LINQ-szolgáltató elérhető. Ez a dokumentum az alapvető LINQ-lekérdezések létrehozásának és használatának három fázisát ismerteti.

A lekérdezési művelet három szakasza

A LINQ lekérdezési műveletek három műveletből állnak:

  1. Szerezze be az adatforrást vagy az adatforrásokat.

  2. Hozza létre a lekérdezést.

  3. Hajtsa végre a lekérdezést.

A LINQ-ban a lekérdezés végrehajtása eltér a lekérdezés létrehozásához. Csak azzal, hogy létrehozza a lekérdezést, nem fog adatokat lekérni. Ezt a pontot a témakör későbbi részében részletesebben tárgyaljuk.

Az alábbi példa egy lekérdezési művelet három részét mutatja be. A példa egy egész számokból álló tömböt használ a bemutató célokra. Ugyanezek a fogalmak azonban más adatforrásokra is érvényesek.

Megjegyzés:

A Fordítás lap, Projekt Tervező (Visual Basic) oldalon győződjön meg arról, hogy az Option infer beállítása bekapcsolva.

' Data source.
Dim numbers() As Integer = {0, 1, 2, 3, 4, 5, 6}

' Query creation.
Dim evensQuery = From num In numbers
                 Where num Mod 2 = 0
                 Select num

' Query execution.
For Each number In evensQuery
    Console.Write(number & " ")
Next

Kimenet:

0 2 4 6

Az adatforrás

Mivel az előző példában szereplő adatforrás egy tömb, implicit módon támogatja az általános IEnumerable<T> felületet. Ez a tény lehetővé teszi, hogy egy tömböt használjon adatforrásként egy LINQ-lekérdezéshez. Azokat a típusokat, amelyek támogatják a IEnumerable<T>-t vagy egy származtatott felületet, mint például a generikus IQueryable<T>-et, lekérdezhető típusoknaknevezzük.

Implicit módon lekérdezhető típusként a tömb nem igényel módosítást vagy speciális kezelést a LINQ-adatforrásként való használathoz. Ugyanez érvényes minden olyan gyűjteménytípusra, amely támogatja IEnumerable<T>a .NET-keretrendszer osztálytárában lévő általános List<T>Dictionary<TKey,TValue>és egyéb osztályokat is.

Ha a forrásadatok még nem implementálják IEnumerable<T>, linq-szolgáltatóra van szükség az adatforrás szabványos lekérdezési operátorainak működéséhez. A LINQ–XML például egy XML-dokumentum lekérdezésre alkalmas XElement típusba való betöltésének munkáját kezeli, ahogyan az az alábbi példában is látható. A standard lekérdezési operátorokról további információt a Standard lekérdezési operátorok áttekintése (Visual Basic) című témakörben talál.

' Create a data source from an XML document.
Dim contacts = XElement.Load("c:\myContactList.xml")

A LINQ to SQL használatával először a tervezéskor hozhat létre objektum-relációs leképezést, akár manuálisan, akár a Visual Studio LINQ to SQL eszközeivel. A lekérdezéseket az objektumokra írja, és futtatáskor az SQL-hez írt LINQ kezeli az adatbázissal folytatott kommunikációt. Az alábbi példában customers egy adott táblát jelöl az adatbázisban, és Table<TEntity> támogatja az általános IQueryable<T>.

' Create a data source from a SQL table.
Dim db As New DataContext("C:\Northwind\Northwnd.mdf")
Dim customers As Table(Of Customer) = db.GetTable(Of Customer)

A különböző LINQ-szolgáltatók dokumentációjában további információt talál arról, hogyan hozhat létre bizonyos típusú adatforrásokat. (A szolgáltatók listáját lásd: LINQ (Language-Integrated Query).) Az alapvető szabály egyszerű: a LINQ-adatforrás minden olyan objektum, amely támogatja az általános IEnumerable<T> felületet, vagy egy olyan felület, amely örökli azt.

Megjegyzés:

Az olyan típusok, mint amelyek ArrayList támogatják a nem általános IEnumerable felületet, LINQ-adatforrásként is használhatók. Egy ArrayList példát a használatára az Útmutató: TömbLista lekérdezése LINQ segítségével (Visual Basic) részben találhat.

A lekérdezés

A lekérdezésben megadhatja, hogy milyen adatokat szeretne lekérni az adatforrásból vagy forrásokból. Azt is megadhatja, hogy az adatok hogyan legyenek rendezve, csoportosítva vagy strukturálva a visszaadása előtt. A lekérdezések létrehozásának engedélyezéséhez a Visual Basic új lekérdezési szintaxist épített be a nyelvbe.

Amikor végrehajtja, a következő példában szereplő lekérdezés egy egész szám tömbből visszaadja az összes páros számot. numbers

' Data source.
Dim numbers() As Integer = {0, 1, 2, 3, 4, 5, 6}

' Query creation.
Dim evensQuery = From num In numbers
                 Where num Mod 2 = 0
                 Select num

' Query execution.
For Each number In evensQuery
    Console.Write(number & " ")
Next

A lekérdezési kifejezés három záradékot tartalmaz: From, Whereés Select. Az egyes lekérdezési kifejezési záradékok konkrét függvényét és célját az Alapszintű lekérdezési műveletek (Visual Basic) ismertetik. További információ: Lekérdezések. Vegye figyelembe, hogy a LINQ-ban a lekérdezésdefiníciók gyakran egy változóban lesznek tárolva, és később lesznek végrehajtva. A lekérdezési változónak, például evensQuery az előző példában, lekérdezhető típusnak kell lennie. A evensQuery típusa IEnumerable(Of Integer), amit a fordító rendel hozzá helyi típuskövetkeztetéssel.

Fontos megjegyezni, hogy maga a lekérdezési változó nem hajt végre műveletet, és nem ad vissza adatokat. Csak a lekérdezésdefiníciót tárolja. Az előző példában ez a For Each ciklus hajtja végre a lekérdezést.

Lekérdezés végrehajtása

A lekérdezés végrehajtása nem azonos a lekérdezések létrehozásával. A lekérdezés létrehozása határozza meg a lekérdezést, de a végrehajtást egy másik mechanizmus aktiválja. A lekérdezések a definiálás után azonnal végrehajthatók (azonnali végrehajtás), vagy a definíció tárolható, és a lekérdezés később is végrehajtható (halasztott végrehajtás).

Halasztott végrehajtás

Egy tipikus LINQ-lekérdezés hasonlít az előző példában szereplő lekérdezésre, amelyben evensQuery definiálva van. Létrehozza a lekérdezést, de nem hajtja végre azonnal. Ehelyett a lekérdezésdefiníció a lekérdezési változóban evensQuerylesz tárolva. A lekérdezést később hajthatja végre, általában egy For Each ciklus használatával, amely egy értéksorozatot ad vissza, vagy egy szabványos lekérdezési operátor ( például Count vagy Max. Ezt a folyamatot halasztott végrehajtásnak nevezzük.

' Query execution that results in a sequence of values.
For Each number In evensQuery
    Console.Write(number & " ")
Next

' Query execution that results in a single value.
Dim evens = evensQuery.Count()

Értékek sorozata esetén a lekért adatokat a ciklus iterációs változójával érheti el (For Eachaz előző példábannumber). Mivel a lekérdezési változó a evensQuerylekérdezési eredmények helyett a lekérdezésdefiníciót tartalmazza, a lekérdezést a lekérdezési változó többszöri használatával a lehető leggyakrabban végrehajthatja. Előfordulhat például, hogy az alkalmazásban van egy adatbázis, amelyet egy külön alkalmazás folyamatosan frissít. Miután létrehozott egy olyan lekérdezést, amely adatokat kér le az adatbázisból, ciklus használatával For Each többször is végrehajthatja a lekérdezést, és minden alkalommal lekérheti a legfrissebb adatokat.

Az alábbi példa a késleltetett végrehajtás működését mutatja be. evensQuery2 az előző példákhoz hasonlóan történő definiálása és For Each ciklussal való végrehajtása után az adatforrás numbers egyes elemei módosulnak. Ezután egy második For Each hurok ismét fut evensQuery2. Az eredmények a második alkalommal eltérőek, mert a For Each ciklus ismét végrehajtja a lekérdezést, a benne lévő numbersúj értékekkel.

Dim numberArray() = {0, 1, 2, 3, 4, 5, 6}

Dim evensQuery2 = From num In numberArray
                  Where num Mod 2 = 0
                  Select num

Console.WriteLine("Evens in original array:")
For Each number In evensQuery2
    Console.Write("  " & number)
Next
Console.WriteLine()

' Change a few array elements.
numberArray(1) = 10
numberArray(4) = 22
numberArray(6) = 8

' Run the same query again.
Console.WriteLine(vbCrLf & "Evens in changed array:")
For Each number In evensQuery2
    Console.Write("  " & number)
Next
Console.WriteLine()

Kimenet:

Evens in original array:

0 2 4 6

Evens in changed array:

0 10 2 22 8

Azonnali végrehajtás

A lekérdezések halasztott végrehajtásakor a lekérdezésdefiníció egy lekérdezési változóban lesz tárolva későbbi végrehajtás céljából. Az azonnali végrehajtás során a lekérdezés a definíció időpontjában lesz végrehajtva. A végrehajtás akkor aktiválódik, ha olyan metódust alkalmaz, amely hozzáférést igényel a lekérdezés eredményének egyes elemeihez. Az azonnali végrehajtást gyakran a szabványos lekérdezési operátorok egyikével kényszerítik ki, amelyek egyetlen értékeket adnak vissza. Ilyenek például a Count, Max, Average és First. Ezek a standard lekérdezési operátorok az alkalmazásuk után azonnal végrehajtják a lekérdezést egy adott eredmény kiszámításához és visszaadásához. Az önálló értékeket visszaadó szabványos lekérdezési operátorokról további információt az Aggregációs műveletek, az Elemműveletek és a Kvantitációs műveletek című témakörben talál.

Az alábbi lekérdezés a páros számok számát adja vissza egész számok tömbjében. A lekérdezésdefiníció nincs mentve, és numEvens egyszerű Integer.

Dim numEvens = (From num In numbers
                Where num Mod 2 = 0
                Select num).Count()

Ugyanezt az eredményt a metódussal Aggregate érheti el.

Dim numEvensAgg = Aggregate num In numbers
                  Where num Mod 2 = 0
                  Select num
                  Into Count()

A lekérdezés végrehajtását úgy is kényszerítheti, hogy meghívja a ToListToArray metódust egy lekérdezésre (azonnali) vagy lekérdezési változóra (halasztva), ahogyan az az alábbi kódban látható.

' Immediate execution.
Dim evensList = (From num In numbers
                 Where num Mod 2 = 0
                 Select num).ToList()

' Deferred execution.
Dim evensQuery3 = From num In numbers
                  Where num Mod 2 = 0
                  Select num
' . . .
Dim evensArray = evensQuery3.ToArray()

Az előző példákban evensQuery3 egy lekérdezési változó, de evensList egy lista, és evensArray tömb.

Különösen hasznos lehet ToList vagy ToArray használata az azonnali végrehajtás kényszerítésére olyan esetekben, amikor azonnal végre szeretné hajtani a lekérdezést és az eredményeket egy gyűjteményobjektumban kívánja tárolni. További információ ezekről a módszerekről: Adattípusok konvertálása.

Lekérdezést is végrehajthat egy IEnumerable módszerrel, például a IEnumerable.GetEnumerator metódussal.

Lásd még