Udostępnij za pomocą


Pisanie pierwszego zapytania LINQ (Visual Basic)

Zapytanie to wyrażenie, które pobiera dane ze źródła danych. Zapytania są wyrażane w dedykowanym języku zapytań. W czasie różne języki zostały opracowane dla różnych typów źródeł danych, na przykład SQL dla relacyjnych baz danych i XQuery dla języka XML. Dzięki temu deweloper aplikacji musi nauczyć się nowego języka zapytań dla każdego typu źródła danych lub obsługiwanego formatu danych.

Language-Integrated Query (LINQ) upraszcza sytuację, oferując spójny model do pracy z danymi w różnych rodzajach źródeł danych i formatach. W zapytaniu LINQ zawsze pracujesz z obiektami. Te same podstawowe wzorce kodowania służą do wykonywania zapytań i przekształcania danych w dokumentach XML, bazach danych SQL, ADO.NET zestawach danych i jednostkach, kolekcjach programu .NET Framework oraz innych źródłach lub formatach, dla których jest dostępny dostawca LINQ. W tym dokumencie opisano trzy fazy tworzenia i używania podstawowych zapytań LINQ.

Trzy etapy operacji zapytania

Operacje zapytań LINQ składają się z trzech akcji:

  1. Uzyskaj źródło lub źródła danych.

  2. Utwórz zapytanie.

  3. Wykonaj zapytanie.

W LINQ wykonywanie zapytania różni się od tworzenia zapytania. Nie pobierasz żadnych danych tylko przez utworzenie zapytania. Ten punkt został omówiony bardziej szczegółowo w dalszej części tego tematu.

Poniższy przykład ilustruje trzy części operacji zapytania. W przykładzie użyto tablicy liczb całkowitych jako wygodnego źródła danych do celów demonstracyjnych. Jednak te same pojęcia dotyczą również innych źródeł danych.

Uwaga / Notatka

Na stronie kompilowania, Project Designer (Visual Basic), upewnij się, że opcja wnioskowania jest ustawiona na Włączone.

' 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

Wyjście:

0 2 4 6

Źródło danych

Ponieważ źródło danych w poprzednim przykładzie jest tablicą, niejawnie obsługuje interfejs ogólny IEnumerable<T> . Jest to fakt, że umożliwia użycie tablicy jako źródła danych dla zapytania LINQ. Typy obsługujące IEnumerable<T> lub pochodny interfejs, taki jak ogólny IQueryable<T>, są nazywane typami z możliwością wykonywania zapytań.

Jako niejawnie możliwy do wykonania zapytania typ tablicy nie wymaga modyfikacji ani specjalnego traktowania, aby służyć jako źródło danych LINQ. To samo dotyczy dowolnego typu kolekcji, który obsługuje IEnumerable<T>, w tym ogólne List<T>, Dictionary<TKey,TValue>i inne klasy w bibliotece klas programu .NET Framework.

Jeśli dane źródłowe jeszcze nie implementują IEnumerable<T>, dostawca LINQ jest potrzebny do zaimplementowania funkcji standardowych operatorów zapytań dla tego źródła danych. Na przykład, LINQ to XML zajmuje się ładowaniem dokumentu XML do typu, na którym można wykonywać zapytania, jak pokazano w poniższym przykładzie. Aby uzyskać więcej informacji na temat standardowych operatorów zapytań, zobacz Omówienie standardowych operatorów zapytań (Visual Basic).

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

W przypadku LINQ to SQL najpierw tworzysz mapowanie relacyjno-obiektowe w czasie projektowania, ręcznie lub przy użyciu narzędzi LINQ to SQL Tools w programie Visual Studio. Zapytania są zapisywane względem obiektów, a w czasie wykonywania LINQ to SQL obsługuje komunikację z bazą danych. W poniższym przykładzie customers reprezentuje określoną tabelę w bazie danych i Table<TEntity> obsługuje ogólne 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)

Aby uzyskać więcej informacji na temat tworzenia określonych typów źródeł danych, zobacz dokumentację różnych dostawców LINQ. (Aby uzyskać listę tych dostawców, zobacz LINQ (Language-Integrated Query)). Podstawowa reguła jest prosta: źródło danych LINQ to dowolny obiekt obsługujący interfejs ogólny IEnumerable<T> lub interfejs dziedziczony z niego.

Uwaga / Notatka

Typy, takie jak ArrayList obsługują interfejs niegeneryczny IEnumerable , mogą być również używane jako źródła danych LINQ. Aby zapoznać się z przykładem korzystającym z elementu ArrayList, zobacz Instrukcje: wykonywanie zapytań o ArrayList przy użyciu LINQ (Visual Basic).

Zapytanie

W zapytaniu określasz informacje, które chcesz pobrać ze źródła danych lub źródeł. Istnieje również możliwość określenia sposobu sortowania, grupowania lub struktury tych informacji przed ich zwróceniem. Aby włączyć tworzenie zapytań, język Visual Basic włączył nową składnię zapytań do języka.

Zapytanie w poniższym przykładzie, po wykonaniu, zwraca wszystkie liczby parzyste z tablicy całkowitej. 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

Wyrażenie zapytania zawiera trzy klauzule: From, Wherei Select. Konkretna funkcja i przeznaczenie każdej klauzuli wyrażenia zapytania jest omawiana w temacie Basic Query Operations (Visual Basic) (Podstawowe operacje zapytań (Visual Basic). Aby uzyskać więcej informacji, zobacz Zapytania. Należy pamiętać, że w linQ definicja zapytania jest często przechowywana w zmiennej i wykonywana później. Zmienna kwerendy, taka jak evensQuery w poprzednim przykładzie, musi być typem z możliwością wykonywania zapytań. Typ evensQuery to IEnumerable(Of Integer), przypisany przez kompilator przy użyciu wnioskowania typu lokalnego.

Należy pamiętać, że sama zmienna kwerendy nie podejmuje żadnej akcji i nie zwraca żadnych danych. Przechowuje tylko definicję zapytania. W poprzednim przykładzie jest to pętla For Each wykonująca zapytanie.

Wykonywanie zapytania

Wykonywanie zapytania jest oddzielone od tworzenia zapytań. Tworzenie zapytania definiuje zapytanie, ale wykonywanie jest wyzwalane przez inny mechanizm. Zapytanie można wykonać natychmiast po zdefiniowaniu (natychmiastowe wykonanie) lub przechowywać definicję, a zapytanie można wykonać później (odroczone wykonanie).

Odroczone wykonanie

Typowe zapytanie LINQ przypomina zapytanie w poprzednim przykładzie, w którym evensQuery jest definiowane. Tworzy zapytanie, ale nie wykonuje go natychmiast. Zamiast tego definicja zapytania jest przechowywana w zmiennej kwerendy evensQuery. Zapytanie jest wykonywane później, zazwyczaj przy użyciu For Each pętli, która zwraca sekwencję wartości lub stosując standardowy operator zapytania, taki jak Count lub Max. Ten proces jest nazywany odroczonym wykonaniem.

' 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()

W przypadku sekwencji wartości uzyskujesz dostęp do pobranych danych przy użyciu zmiennej iteracji w For Each pętli (number w poprzednim przykładzie). Ponieważ zmienna kwerendy , evensQueryprzechowuje definicję zapytania, a nie wyniki zapytania, możesz wykonać zapytanie tak często, jak chcesz, używając zmiennej kwerendy więcej niż jeden raz. Na przykład możesz mieć bazę danych w aplikacji, która jest stale aktualizowana przez oddzielną aplikację. Po utworzeniu zapytania, które pobiera dane z tej bazy danych, możesz użyć For Each pętli do wielokrotnego wykonywania zapytania, pobierając najnowsze dane za każdym razem.

W poniższym przykładzie pokazano, jak działa wykonywanie odroczone. Po zdefiniowaniu evensQuery2 i wykonaniu za pomocą pętli For Each, jak w poprzednich przykładach, niektóre elementy w źródle danych numbers ulegają zmianie. Następnie po raz drugi uruchamiana jest For Each pętla evensQuery2. Wyniki są inne po raz drugi, ponieważ pętla For Each ponownie wykonuje zapytanie, używając nowych wartości w pliku numbers.

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()

Wyjście:

Evens in original array:

0 2 4 6

Evens in changed array:

0 10 2 22 8

Natychmiastowe wykonanie

Podczas odroczonego wykonywania zapytań definicja zapytania jest przechowywana w zmiennej zapytania na potrzeby późniejszego wykonywania. W bezpośrednim wykonaniu zapytanie jest wykonywane w momencie jego definicji. Wykonanie jest wyzwalane podczas stosowania metody, która wymaga dostępu do poszczególnych elementów wyniku zapytania. Natychmiastowe wykonywanie często jest wymuszane przy użyciu jednego ze standardowych operatorów zapytań, które zwracają pojedyncze wartości. Przykłady to Count, , MaxAveragei First. Te standardowe operatory zapytań wykonują zapytanie natychmiast po ich zastosowaniu, aby obliczyć i zwrócić pojedynczy wynik. Aby uzyskać więcej informacji na temat standardowych operatorów zapytań, które zwracają pojedyncze wartości, zobacz Operacje agregacji, Operacje elementów i Operacje kwantyfikatora.

Poniższe zapytanie zwraca liczbę liczb parzysnych w tablicy liczb całkowitych. Definicja zapytania nie jest zapisywana i numEvens jest prostą Integerdefinicją .

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

Ten sam wynik można osiągnąć przy użyciu Aggregate metody .

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

Możesz również wymusić wykonanie zapytania, wywołując metodę ToList lub ToArray dla zapytania (natychmiastowego) lub zmiennej zapytania (odroczonej), jak pokazano w poniższym kodzie.

' 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()

W poprzednich przykładach evensQuery3 jest zmienną kwerendy, ale evensList jest listą i evensArray jest tablicą.

Użycie ToList lub ToArray do wymuszenia natychmiastowego wykonania jest szczególnie przydatne w scenariuszach, gdy chcesz natychmiast wykonać zapytanie i zbuforować wyniki w jednej kolekcji. Aby uzyskać więcej informacji na temat tych metod, zobacz Konwertowanie typów danych.

Można również wykonać zapytanie, korzystając z metody IEnumerable, takiej jak IEnumerable.GetEnumerator.

Zobacz także