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


Típuskapcsolatok a lekérdezési műveletekben (Visual Basic)

A nyelvvel integrált lekérdezési (LINQ) lekérdezési műveletekben használt változók erősen be vannak gépelve, és kompatibilisek kell lenniük egymással. Erős gépelést használ az adatforrásban, magában a lekérdezésben és a lekérdezés végrehajtásában. Az alábbi ábra egy LINQ-lekérdezés leírásához használt kifejezéseket azonosítja. A lekérdezés részeiről további információt az Egyszerű lekérdezési műveletek (Visual Basic) című témakörben talál.

Screenshot showing a pseudocode query with elements highlighted.

A lekérdezés tartományváltozójának típusának kompatibilisnek kell lennie az adatforrás elemeinek típusával. A lekérdezési változó típusának kompatibilisnek kell lennie a záradékban Select meghatározott sorrendelemgel. Végül a sorozatelemek típusának kompatibilisnek kell lennie a lekérdezést végrehajtó utasításban For Each használt ciklusvezérlő változó típusával is. Ez az erős gépelés megkönnyíti a típushibák azonosítását fordításkor.

A Visual Basic a helyi típusú következtetés, más néven implicit gépelés implementálásával teszi kényelmessé az erős gépelést. Ez a funkció az előző példában használatos, és a LINQ-mintákban és a dokumentációban is megjelenik. A Visual Basicben a helyi típusú következtetés egyszerűen egy Dim záradék nélküli As utasítással történik. Az alábbi példában city erősen sztringként van begépelve.

Dim city = "Seattle"

Feljegyzés

A helyi típusú következtetés csak akkor működik, ha Option Infer be van állítva On. További információ: Option Infer Statement.

Ha azonban helyi típusú következtetést is használ egy lekérdezésben, az adatforrás változói, a lekérdezési változó és a lekérdezés végrehajtási ciklusa között ugyanazok a típuskapcsolatok találhatók. Ha LINQ-lekérdezéseket ír, vagy a dokumentációban szereplő mintákkal és kódmintákkal dolgozik, érdemes alapszintű ismeretekkel rendelkezni az ilyen típusú kapcsolatokról.

Előfordulhat, hogy explicit típust kell megadnia egy olyan tartományváltozóhoz, amely nem felel meg az adatforrásból visszaadott típusnak. A tartományváltozó típusát záradék As használatával adhatja meg. Ez azonban hibát eredményez, ha az átalakítás szűkítő konverzió , és Option Strict a beállítás értéke On. Ezért javasoljuk, hogy végezze el az átalakítást az adatforrásból lekért értékeken. A metódus használatával Cast az adatforrás értékeit explicit tartományváltozótípussá alakíthatja. A záradékban Select kijelölt értékeket a tartományváltozó típusától eltérő explicit típusra is átadhatja. Ezeket a pontokat az alábbi kód szemlélteti.

Dim numbers1() As Integer = {1, 2, 4, 16, 32, 64}
Dim numbers2() As Double = {5.0#, 10.0#, 15.0#}

' This code does not result in an error.
Dim numberQuery1 = From n As Integer In numbers1 Where n > 5

' This code results in an error with Option Strict set to On. The type Double
' cannot be implicitly cast as type Integer.
Dim numberQuery2 = From n As Integer In numbers2 Where n > 5

' This code casts the values in the data source to type Integer. The type of
' the range variable is Integer.
Dim numberQuery3 = From n In numbers2.Cast(Of Integer)() Where n > 5

' This code returns the value of the range variable converted to Integer. The type of
' the range variable is Double.
Dim numberQuery4 = From n In numbers2 Where n > 5 Select CInt(n)

A forrásadatok teljes elemeit visszaadó lekérdezések

Az alábbi példa egy LINQ-lekérdezési műveletet mutat be, amely a forrásadatokból kiválasztott elemek sorozatát adja vissza. A forrás namessztringtömböt tartalmaz, a lekérdezés kimenete pedig egy sztringeket tartalmazó sorozat, amely az M betűvel kezdődik.

Dim names = {"John", "Rick", "Maggie", "Mary"}
Dim mNames = From name In names
             Where name.IndexOf("M") = 0
             Select name

For Each nm In mNames
    Console.WriteLine(nm)
Next

Ez egyenértékű a következő kóddal, de sokkal rövidebb és könnyebben írható. A Visual Basic előnyben részesített stílusa a helyi típusú következtetésre való támaszkodás a lekérdezésekben.

Dim names2 = {"John", "Rick", "Maggie", "Mary"}
Dim mNames2 As IEnumerable(Of String) =
    From name As String In names
    Where name.IndexOf("M") = 0
    Select name

For Each nm As String In mNames
    Console.WriteLine(nm)
Next

Az alábbi kapcsolatok az előző kód mindkét példájában léteznek, függetlenül attól, hogy a típusok implicit módon vagy explicit módon vannak meghatározva.

  1. Az adatforrás nameselemeinek típusa a lekérdezés tartományváltozójának nametípusa.

  2. A kiválasztott objektum típusa határozza namemeg a lekérdezési változó típusát. mNames Itt name van egy sztring, így a lekérdezési változó iEnumerable(Of String) a Visual Basicben.

  3. A megadott mNames lekérdezés a ciklusban For Each lesz végrehajtva. A ciklus a lekérdezés végrehajtásának eredménye felett iterál. Mivel mNamesa végrehajtáskor sztringsorozatot ad vissza, a ciklus iterációs változója nmis egy sztring.

Lekérdezések, amelyek egy mezőt adnak vissza a kijelölt elemekből

Az alábbi példa egy LINQ–SQL-lekérdezési műveletet mutat be, amely egy olyan sorozatot ad vissza, amely az adatforrásból kiválasztott egyes elemeknek csak egy részét tartalmazza. A lekérdezés adatforrásként egy objektumgyűjteményt Customer vesz fel, és csak az eredmény tulajdonságát Name projekteli. Mivel az ügyfélnév egy sztring, a lekérdezés kimenetként sztringsorozatot hoz létre.

' Method GetTable returns a table of Customer objects.
Dim customers = db.GetTable(Of Customer)()
Dim custNames = From cust In customers
                Where cust.City = "London"
                Select cust.Name

For Each custName In custNames
    Console.WriteLine(custName)
Next

A változók közötti kapcsolatok olyanok, mint az egyszerűbb példában.

  1. Az adatforrás customerselemeinek típusa a lekérdezés tartományváltozójának custtípusa. Ebben a példában ez a típus .Customer

  2. Az Select utasítás az Name egyes Customer objektumok tulajdonságát adja vissza a teljes objektum helyett. Mivel Name egy sztringről van szó, custNamesa lekérdezési változó ismét az IEnumerable(Of String) lesz, nem pedig az Customer.

  3. Mivel custNames sztringsorozatot jelöl, a For Each hurok iterációs változójának custNamesztringnek kell lennie.

Helyi típusú következtetés nélkül az előző példa nehézkesebb lenne írni és megérteni, ahogy az alábbi példa is mutatja.

' Method GetTable returns a table of Customer objects.
 Dim customers As Table(Of Customer) = db.GetTable(Of Customer)()
 Dim custNames As IEnumerable(Of String) =
     From cust As Customer In customers
     Where cust.City = "London"
     Select cust.Name

 For Each custName As String In custNames
     Console.WriteLine(custName)
 Next

Névtelen típusokat igénylő lekérdezések

Az alábbi példa egy összetettebb helyzetet mutat be. Az előző példában kényelmetlen volt az összes változó típusának explicit megadása. Ebben a példában lehetetlen. Ahelyett, hogy teljes Customer elemeket választanál ki az adatforrásból, vagy egy mezőt minden elemből, a Select lekérdezés záradéka az eredeti Customer objektum két tulajdonságát adja vissza: Name és City. A záradékra válaszul a Select fordító egy névtelen típust határoz meg, amely tartalmazza ezt a két tulajdonságot. A ciklusban történő nameCityQuery végrehajtás eredménye az For Each új névtelen típusú példányok gyűjteménye. Mivel a névtelen típus nem rendelkezik használható névvel, nem adhatja meg a típust nameCityQuery vagy custInfo explicit módon. Vagyis névtelen típus esetén a név helyett nincs használandó StringIEnumerable(Of String)típusnév. További információ: Névtelen típusok.

' Method GetTable returns a table of Customer objects.
Dim customers = db.GetTable(Of Customer)()
Dim nameCityQuery = From cust In customers
                    Where cust.City = "London"
                    Select cust.Name, cust.City

For Each custInfo In nameCityQuery
    Console.WriteLine(custInfo.Name)
Next

Bár az előző példában nem lehet típusokat megadni az összes változóhoz, a kapcsolatok változatlanok maradnak.

  1. Az adatforrás elemeinek típusa ismét a lekérdezés tartományváltozójának típusa. Ebben a példában cust a Customer.

  2. Mivel az Select utasítás névtelen típust hoz létre, nameCityQuerya lekérdezési változót implicit módon névtelen típusként kell beírni. A névtelen típusnak nincs használható neve, ezért nem adható meg explicit módon.

  3. A ciklus iterációs változójának típusa a For Each 2. lépésben létrehozott névtelen típus. Mivel a típus nem rendelkezik használható névvel, a ciklus iterációs változójának típusát implicit módon kell meghatározni.

Lásd még