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


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

A lekérdezés 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.

A Language-Integrated Query (LINQ) egy consis sátormód l használatával leegyszerűsíti a helyzetet, amely különféle adatforrások és formátumok adataival dolgozik. 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 a 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 lekérdezés létrehozásával nem kér le adatokat. 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.

Feljegyzés

A Fordítás lapon a Project Tervező (Visual Basic), győződjön meg arról, hogy az Option infer értéke be van kapcsolva.

' 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. Az olyan típusokat, amelyek támogatják IEnumerable<T> vagy egy származtatott felületet, például az általánostIQueryable<T>, lekérdezhető típusoknak nevezzü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>az általánost List<T>Dictionary<TKey,TValue>és a .NET-keretrendszer osztálytár más osztályát 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-ről SQL-hez először a tervezéskor hozhat létre objektum-relációs leképezést manuálisan, vagy a LINQ és az SQL Tools használatával a Visual Studio Visual Studióban . 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 (Nyelvbe integrált lekérdezés).) 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.

Feljegyzé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. Ha például egy ArrayListtömblistát használ, olvassa el a How to: Query an ArrayList with LINQ (Visual Basic) (ArrayList with LINQ (Visual Basic) című témakört.

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ámbó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 típust evensQueryIEnumerable(Of Integer)a fordító rendeli hozzá helyi típusú kö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 (numberaz előző példábanFor Each). 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. A ciklus definiálása For Each és végrehajtása után evensQuery2 az előző példákhoz hasonlóan az adatforrás numbers egyes elemei módosulnak. Ezután ismét fut evensQuery2 egy második For Each hurok. 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 Countkövetkezők: , MaxAverageé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.

Az azonnali végrehajtás használata ToList vagy ToArray kényszerítése különösen akkor hasznos, ha a lekérdezést azonnal végre szeretné hajtani, és egyetlen gyűjteményobjektumban gyorsítótárazza az eredményeket. További információ ezekről a módszerekről: Adattípusok konvertálása.

Azt is okozhatja, hogy egy lekérdezést egy IEnumerable olyan módszerrel hajt végre, mint a IEnumerable.GetEnumerator metódus.

Lásd még