LINQ w Microsoft Visual Basic 'zapytanie pobierające wszystkie liczby z kolekcji 'zmienna zapytanie jest typu: System.Collections.Generic.IEnumerable(Of Integer) Dim zapytanie = From wiersz In liczby 'lub zapytanie = From wiersz In liczby Select wiersz : Console.WriteLine(x) : Zapytania służące do wyświetlenia kolekcji wierszy, zaczynają się od słowa kluczowego From, po którym należy zdefiniować nazwę zmiennej, która będzie reprezentowała wiersz. Po słowie kluczowym In należy wpisać nazwę kolekcji, z której dane zostaną pobrane lub w nawiasach okrągłych zdefiniować nowe zapytanie (tzw. podzapytanie), będące obowiązkowo kolekcją. Operator Select służy do wskazania zestawu danych do zwrócenia w ramach zapytania (lub podzapytania). Jeżeli zmienna po słowie From zawiera zestaw kolumn w ramach danej struktury, to zwrócenie konkretnych kolumn następuje po wpisaniu ich nazw po kropce. 'zapytanie pobierające wartości bezwzględne liczb z kolekcji Dim zapytanie = From wiersz In liczby Select Math.Abs(wiersz) Przykład powyżej pokazuje, że w zapytaniu można umieszczać funkcje zarówno zdefiniowane w ramach środowiska, jak również własne. 'liczby posortowane rosnąco Dim zapytanie = From wiersz In liczby Select wiersz Order By wiersz 'liczby posortowane malejąco zapytanie = From wiersz In liczby Select wiersz Order By wiersz Descending Przykład powyżej pokazuje w jaki sposób wykonuje się sortowanie danych w ramach zapytania. Należy w tym celu umieścić operator Order By, a po nim zestaw pojedynczych danych, po których ma nastąpić sortowanie. Słowo kluczowe Descending umożliwia sortowanie malejące (bez tego słowa, sortowanie następuje rosnąco). Uwagę należy zwrócić na kolejność występowania po sobie słów kluczowych. Ma to istotny wpływ na poprawność składniową zapytania.
Dim liczby() As Integer = {0, 1, 2, 3, 4, 5} 'zwracanie wielu kolumn Dim zapytanie = From wiersz In liczby Select liczba = wiersz, wynik = wiersz * wiersz Console.WriteLine("{0} x {1} = {2}", x.liczba, x.liczba, x.wynik) Powyższy przykład pokazuje, że w zapytaniach można umieszczać działania matematyczne. Dodatkowo, jest to przykład ilustrujący sposób zwrócenia dwóch wartości w ramach wiersza. Dim liczby() As Integer = {0, 1, 2, 3, 4, 5} 'zwrócenie wartości parzystych Dim zapytanie = From wiersz In liczby Where wiersz Mod 2 = 0 W celu zwrócenia wybranych wartości z kolekcji należy zastosować składnię polecenia z operatorem Where. Zasada tworzenia warunku jest podobna jak w przypadku If (mają zastosowanie te same operatory logiczne). Poniższy kod przedstawia użycie operatora Join służącego do łączenia kolekcji pod danym warunkiem zgodności par wartości zmiennych. Słowo kluczowe Equals oznacza zgodność. Structure para Dim liczba As Integer Dim tekst As String End Structure Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Dim pozycja As para Dim liczby_polski As New List(Of para) Dim liczby_angielski As New List(Of para) pozycja.liczba = 1 pozycja.tekst = "jeden" : liczby_polski.add(pozycja) pozycja.tekst = "one" : liczby_angielski.add(pozycja) pozycja.liczba = 2 pozycja.tekst = "dwa" : liczby_polski.add(pozycja) pozycja.tekst = "two" : liczby_angielski.add(pozycja) pozycja.liczba = 3 pozycja.tekst = "trzy" : liczby_polski.add(pozycja) pozycja.tekst = "three" : liczby_angielski.add(pozycja) Dim zapytanie = From polski In liczby_polski Join angielski In liczby_angielski On polski.liczba Equals angielski.liczba Select pl = polski.tekst, eng = angielski.tekst, l = polski.liczba Console.WriteLine("Liczba: {0}, po polsku: {1}, po angielsku: {2}", x.l, x.pl, x.eng)
W przykładzie zastosowane zostały dwie kolekcje typu Lista, których typ danych jest strukturą o nazwie para składającą się z dwóch zmiennych. Liczba: 1, po polsku: jeden, po angielsku: one Liczba: 2, po polsku: dwa, po angielsku: two Liczba: 3, po polsku: trzy, po angielsku: three Poniżej znajdują się dwa przykłady, obliczające ilość liczb parzystych w kolekcji. Pierwszy sposób zrealizowany jest z wykorzystaniem metody Count dla kolekcji. Drugi bazuje wyłącznie na samym zapytaniu. Operator Aggregate służy do agregacji danych i jest używany ze słowem Into, a także jedną z metod agregujących / grupujących, tj. Count(), Sum(), itd. Operator Distinct powoduje zwrócenie wartości unikatowych z kolekcji. Należy zwrócić w tym przykładzie uwagę na typ zwracany przez metodę agregującą jest to liczba, nie kolekcja. 'ile w kolekcji jest liczb unikatowych? Dim odpowiedz As Integer = (From wiersz In liczby Distinct).Count lub 'ile w kolekcji jest liczb unikatowych? Dim odpowiedz As Integer = Aggregate wiersz In (From wiersz In liczby Distinct) Into cnt = Count() Poniżej znajduje się przykład dotyczący sumowania wartości liczbowych w kolekcji. W tym celu konieczne było ponowne użycie operatora Aggregate, a z nim metody Sum(). 'ile wynosi suma wszystkich liczb w kolekcji? Dim odpowiedz = Aggregate wiersz In liczby Into l = Sum() Poniższy kod przedstawia sposób na otrzymanie w jednym wierszu dwóch obliczonych wartości w ramach dwóch osobnych podzapytań. 'ile w kolekcji jest liczb parzystych, a ile nieparzystych? Dim odpowiedz = From c In {vbnull} Select parzyste = (Aggregate wiersz In (From w In liczby Where w Mod 2 = 0) Into i = Count()), nieparzyste = (Aggregate wiersz In (From w In liczby Where w Mod 2 <> 0) Into i = Count())
Console.WriteLine("Liczb parzystych: " & odpowiedz(0).parzyste & ", liczb nieparzystych: " & odpowiedz(0).nieparzyste) Poniższy kod przedstawia zapytanie zwracające statystykę występowania znaków w ciągu tekstowym, w tym liter bez rozróżnienia ich wielkości. W celu osiągnięcia prawidłowego wyniku należało utworzyć podzapytanie z operatorem Aggregate, w którym użyta została w warunku Where zmienna litera pochodząca z poziomu wyżej. Zabieg ten umożliwił obliczanie liczby wierszy dla aktualnie rozpatrywanego wiersza z poziomu wyżej, tj. z kolekcji pochodzącej z podzapytania zwracającego małe litery. Dim cytat As String = "Rzec można, że największą tajemnicą świata jest jego poznawalność. A. Einstein" Dim zapytanie = From litera In (From litera In cytat Select litera = litera.tostring.tolower) Distinct Select litera, y = (Aggregate znak In cytat Where znak.tostring.tolower = litera Into l = Count()) Order By litera Console.WriteLine("Znak: " & x.litera & " występuje: " & x.y & " raz(y)") Innym sposobem (i w tym przypadku prostszym) na stworzenie tego typu statystyki jest użycie operatora Group By. Poniższy przykład pokazuje jego zastosowanie. Dim cytat2 As String = "Rzec można, że największą tajemnicą świata jest jego poznawalność. A. Einstein" Dim zapytanie2 = From wiersz In (From litera In cytat2 Select litera = litera.tostring.tolower Group By litera Into y = Count()) Order By wiersz.litera 2 Console.WriteLine("Znak: " & x.litera & " występuje: " & x.y & " raz(y)") Zasadniczą różnicą pomiędzy oboma operatorami jest to, że Group By zawarty jest w ramach operatora From i ostatecznie zwracana jest kolekcja, natomiast Aggregate zwraca jedną wartość. Poniżej znajduje się jeszcze jeden przykład z użyciem operatora Group By. Structure klient Dim imie As String Dim nazwisko As String Dim miejsce_zamieszkania As String End Structure Dim klienci As New List(Of klient) Sub dodaj_klienta(imie As String, nazwisko As String, miejsce_zamieszkania As String) Dim k As klient k.imie = imie k.nazwisko = nazwisko k.miejsce_zamieszkania = miejsce_zamieszkania klienci.add(k) End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click dodaj_klienta("jan", "Kowalski", "Kraków") dodaj_klienta("anna", "Nowak", "Warszawa") dodaj_klienta("barbara", "Nowakowska", "Warszawa") dodaj_klienta("janina", "Zygmunt", "Poznań") dodaj_klienta("teodora", "Kowalska", "Płock") dodaj_klienta("jacek", "Zygmunt", "Kraków") dodaj_klienta("wincenty", "Kowalski", "Kraków") 'wyświetl listę miast posortowaną względem liczby zamieszkujących je klientów malejąco, jednocześnie rosnąco względem nazw miast w grupie liczby klientów, pokaż miasto i liczbę klientów Dim odpowiedz = From lista In (From wiersz In klienci Select wiersz Group By wiersz.miejsce_zamieszkania Into liczba = Count()) Order By lista.liczba Descending, lista.miejsce_zamieszkania End Sub For Each x In odpowiedz Console.WriteLine("W mieście: " & x.miejsce_zamieszkania & " mieszka: " & x.liczba & " klientów") Po słowie kluczowym Group By należało umieścić zmienną zawierającą wartości, po których ma nastąpić grupowanie i zliczenie wierszy. Rezultat działania kodu przedstawiony został poniżej. W mieście: Kraków mieszka: 3 klientów W mieście: Warszawa mieszka: 2 klientów W mieście: Płock mieszka: 1 klientów W mieście: Poznań mieszka: 1 klientów Artur Niewiarowski Wydział Fizyki, Matematyki i Informatyki Politechnika Krakowska Kraków 2014