Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Zmienne używane w operacjach zapytań Language-Integrated Query (LINQ) są mocno typizowane i muszą być ze sobą zgodne. Silne wpisywanie jest używane w źródle danych, w samym zapytaniu i w wykonaniu zapytania. Poniższa ilustracja identyfikuje terminy używane do opisywania zapytania LINQ. Aby uzyskać więcej informacji na temat części zapytania, zobacz Podstawowe operacje zapytań (Visual Basic).
Typ zmiennej zakresu w zapytaniu musi być zgodny z typem elementów w źródle danych. Typ zmiennej kwerendy musi być zgodny z elementem sekwencji zdefiniowanym w klauzuli Select . Na koniec typ elementów sekwencji musi być również zgodny z typem zmiennej sterującej pętli, która jest używana w For Each instrukcji wykonującej zapytanie. Silne typowanie ułatwia identyfikację błędów typów podczas kompilacji.
Język Visual Basic ułatwia silne typowanie poprzez implementację wnioskowania typów lokalnych, znanego również jako niejawne typowanie. Ta funkcja jest używana w poprzednim przykładzie i zobaczysz, że jest używana w przykładach LINQ i dokumentacji. W języku Visual Basic wnioskowanie typu lokalnego odbywa się po prostu przy użyciu Dim instrukcji bez klauzuli As . W poniższym przykładzie city jest silnie typizowane jako ciąg.
Dim city = "Seattle"
Uwaga / Notatka
Wnioskowanie typu lokalnego działa tylko wtedy, gdy Option Infer jest ustawione na On. Aby uzyskać więcej informacji, zobacz Instrukcja wnioskowania opcji.
Jednak nawet jeśli używasz wnioskowania typu lokalnego w zapytaniu, relacje tego samego typu są obecne wśród zmiennych w źródle danych, zmiennej zapytania i pętli wykonywania zapytania. Warto mieć podstawową wiedzę na temat tych relacji typów podczas pisania zapytań LINQ lub pracy z przykładami przykładów i kodu w dokumentacji.
Może być konieczne określenie jawnego typu zmiennej zakresu, która nie jest zgodna z typem zwracanym ze źródła danych. Typ zmiennej zakresu można określić przy użyciu klauzuli As . Jednak prowadzi to do błędu, jeśli konwersja jest konwersją zawężającą i Option Strict jest ustawiona na On. W związku z tym zalecamy przeprowadzenie konwersji wartości pobranych ze źródła danych. Wartości ze źródła danych można przekonwertować na jawny typ zmiennej zakresu przy użyciu Cast metody . Można również rzutować wartości wybrane w klauzuli Select na jawny typ, który różni się od typu zmiennej zakresu. Te punkty przedstawiono w poniższym kodzie.
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)
Zapytania zwracające całe elementy danych źródłowych
Poniższy przykład przedstawia operację zapytania LINQ zwracającą sekwencję elementów wybranych z danych źródłowych. Źródło , nameszawiera tablicę ciągów, a dane wyjściowe zapytania to sekwencja zawierająca ciągi rozpoczynające się literą M.
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
Jest to odpowiednik następującego kodu, ale jest znacznie krótszy i łatwiejszy do pisania. Poleganie na wnioskowaniu typu lokalnego w zapytaniach jest preferowanym stylem w języku Visual Basic.
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
W obu poprzednich przykładach kodu istnieją następujące relacje, niezależnie od tego, czy typy są określane niejawnie, czy jawnie.
Typ elementów w źródle danych,
names, jest typem zmiennej zakresu,name, w zapytaniu.Typ wybranego
nameobiektu określa typ zmiennej kwerendy .mNamesOtonameciąg znaków, więc zmienna dla zapytania to IEnumerable(Of String) w Visual Basic.Zapytanie zdefiniowane w pliku
mNamesjest wykonywane wFor Eachpętli. Pętla iteruje wynik wykonywania zapytania. PonieważmNames, gdy jest wykonywany, zwróci sekwencję ciągów, zmienną iteracji pętli ,nmjest również ciągiem.
Zapytania zwracające jedno pole z wybranych elementów
Poniższy przykład przedstawia operację zapytania LINQ to SQL, która zwraca sekwencję zawierającą tylko jedną część każdego elementu wybranego ze źródła danych. Funkcja zapytania przyjmuje kolekcję Customer obiektów jako źródło danych i rzutuje w wyniku tylko właściwość Name. Ponieważ nazwa klienta jest ciągiem, zapytanie tworzy sekwencję ciągów jako dane wyjściowe.
' 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
Relacje między zmiennymi są podobne do tych w prostszym przykładzie.
Typ elementów w źródle danych,
customers, jest typem zmiennej zakresu,cust, w zapytaniu. W tym przykładzie ten typ toCustomer.Instrukcja
SelectzwracaNamewłaściwość każdegoCustomerobiektu zamiast całego obiektu. PonieważNamejest ciągiem, zmienna kwerendy,custNames, ponownie będzie IEnumerable(Of String), a nieCustomer.Ponieważ
custNamesreprezentuje sekwencję ciągów,For Eachzmienna iteracji pętli musicustNamebyć ciągiem.
Bez wnioskowania typu lokalnego poprzedni przykład byłby bardziej uciążliwy do zapisu i zrozumienia, jak pokazano w poniższym przykładzie.
' 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
Zapytania wymagające typów anonimowych
W poniższym przykładzie przedstawiono bardziej złożoną sytuację. W poprzednim przykładzie było niewygodne określenie typów dla wszystkich zmiennych jawnie. W tym przykładzie jest to niemożliwe. Zamiast wybierać całe Customer elementy ze źródła danych lub pojedynczego pola z każdego elementu, klauzula Select w tym zapytaniu zwraca dwie właściwości oryginalnego Customer obiektu: Name i City. W odpowiedzi na klauzulę Select kompilator definiuje typ anonimowy zawierający te dwie właściwości. Wynik wykonywania nameCityQuery w pętli For Each jest kolekcją wystąpień nowego typu anonimowego. Ponieważ typ anonimowy nie ma użytecznej nazwy, nie można określić typu nameCityQuery ani custInfo jawnie. Oznacza to, że w przypadku typu anonimowego nie ma nazwy typu, którą można użyć zamiast String w IEnumerable(Of String). Aby uzyskać więcej informacji, zobacz Typy anonimowe.
' 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
Chociaż nie można określić typów dla wszystkich zmiennych w poprzednim przykładzie, relacje pozostają takie same.
Typ elementów w źródle danych jest ponownie typem zmiennej zakresu w zapytaniu. W tym przykładzie
custjest instancjąCustomer.SelectPonieważ instrukcja generuje typ anonimowy, zmienna kwerendy musinameCityQuerybyć niejawnie wpisywana jako typ anonimowy. Typ anonimowy nie ma nazwy użytecznej i dlatego nie można jawnie określić.Typ zmiennej iteracji w
For Eachpętli jest typem anonimowym utworzonym w kroku 2. Ponieważ typ nie ma użytecznej nazwy, typ zmiennej iteracji pętli musi być określany niejawnie.