Archiwa tagu: linq

C# LINQ to XML

LINQ to XML

Aby wyjaśnić na czym polega technologia LINQ to XML na początku trzeba zgłębić trochę teorii na temat tego języka. LINQ to XML to kolejna technologia LINQ, która opiera się na odczycie i zapisie plików XML. XML z angielskiego Extensible Markup Language, czyli rozszerzalny język znaczników służy do prezentowania danych w uporządkowany sposób. Zaletą tego języka jest to, że jest on niezależny od platformy systemowej. Pliki które będziemy tworzyć za pomocą XML-a są plikami tekstowymi.

Zasada tworzenia treści plików w XML przypomina troszeczkę HTML. Języki te sa podobne z uwagi na wykorzystywanie znaczników w procesie tworzenie pliku. Jest jednak różnica. W HTML nazwy znaczników mamy z góry określone a w XML-u możemy tworzyć je sami. Znaczniki w dokumencie XML umieszczamy w sposób zagnieżdżony ale o tym za chwilkę przy omawianiu tworzenia dokumentów w XML-u. OK, zacznijmy tworzyć coś praktycznego. Poniżej przykład deklaracji pliku XML. W trakcie deklaracji dokumentu XML określamy takie jego właściwości jak wersję, kodowanie.

LINQ to XML
Listing 19.0 Deklaracja dokumentu XML.

Teraz możemy wprowadzać poszczególne elementy. Jak już wcześniej wspomniałem jest kilka zasad którymi powinniśmy się kierować przy tworzeniu dalszej struktury pliku XML.

  • nazwy elementów (znaczników) tworzymy sami,
  • elementy możemy zagnieżdżać w sobie,
  • każdy element musi posiadać znacznik otwierający i zamykający (dobrą praktyką jest, żeby od razu przy tworzeniu jakiegoś elementu tworzyć znacznik otwierający i zamykający wtedy unikniemy błędów i przy większym dokumencie szukania brakującego znacznika),

Poniżej przykład z kilkoma zagnieżdżonymi elementami.

LINQ to XML
Listing 19.1 Przykładowy plik XML.

Należy jeszcze wspomnieć, że dodatkowy przy naszych elementach możemy dodawać dodatkowe informacje. Takie dodatkowe informacje nazywamy atrybutami i dodajemy je w następujący sposób.

LINQ to XML. Deklaracja elementu.
LINQ to XML. Deklaracja elementu.

Przez niektórych niedoceniany ale moim zdaniem niemniej ważnym elementem pliku XML jest komentarz. Komentarze w XML-u dodajemy w poniższy sposób.

LINQ to XML. Dodawanie komentarzy do dokumentu XML.
LINQ to XML. Dodawanie komentarzy do dokumentu XML.

Kod z listingu 19.1 stanowi prosty przykład pliku XML. Moglibyśmy skopiować ten kod, otworzyć notatnik w systemie Windows, skopiować ten kod do naszego pliku i przy zapisywaniu pliku zmienić rozszerzenie pliku na XML i nasz pierwszy plik XML gotowy.

Możemy to także zrobić z poziomu kodu C# w Visual Studio. Aby to zrobić do przestrzeni nazw musimy dodać przestrzeń System.Xml.Linq;, dzięki której będziemy mogli za pomocą C# utworzyć plik XML.

Przy tworzeniu naszego pliku wykorzystamy poniższe instrukcje:

xDocument – deklarujemy nowy plik XML

XDeclaration – deklaracja właściwości naszego odkumentu (wersja, kodowanie itp.)

XElement – dodawanie nowego elementu

XAttribute – dodawanie atrybutu do elementu

XComment – dodawanie komentarza

Teraz spróbujemy utworzyć taką samą strukturę pliku XML jaką przedstawia listing 19.1. Jedyną trudnością jest zagnieżdżenie elementu w elemencie np. zagnieżdżenie elementu <opel> w elemencie <samochod>.

Poniżej pierwszy sposób tworzenia takiego pliku. Polega on na odpowiednim sposobie deklaracji poszczególnych argumentów konstruktora. Poniżej przedstawiam kod dzięki któremu stworzymy dokument XML zgodny z treścią z listingu 19.1. Wykorzystamy w nim instrukcje opisane powyżej.

Listing 19.2 Tworzymy nasz pierwszy plik XML.

Listing 19.2 Tworzymy nasz pierwszy plik XML.
Listing 19.2 Tworzymy nasz pierwszy plik XML.

Zobacz kod.

Pierwszą instrukcją jest konstruktor klasy XDocument, czyli rozpoczynamy tworzenie naszego dokumentu XML. Nasz konstruktor zawiera trzy argumenty, oznaczone różnymi kolorami (listing 19.2). Każdy parametr oddzielamy przecinkiem. Pierwszy parametr (instrukcja XDeclaration), oznaczony kolorem czerwonym, to deklaracja właściwości naszego dokumentu. Drugi argument (instrukcja XComment), oznaczony kolorem pomarańczowym, to komentarz dodany do treści naszego dokumentu. Trzeci argument (instrukcja XElement), oznaczony kolorem niebieskim, to deklaracja naszych elementów. Poleceniem xml.Save(); tworzymy nasz nowy dokument.

Teraz przejdźmy do części gdzie deklarujemy nasze elementy (część niebieska). Poniżej listing 19.3 pokazuje sposób zagnieżdżenia elementów w naszym dokumencie. Poszczególnymi kolorami zaznaczone zostały poszczególne poziomy zagnieżdżenia elementów. W przypadku każdego elementu pierwszym argumentem jest nazwa elementu np. „samochod”, „opel” i „astra”. Zwróćmy uwagę, że drugim parametrem elementu „samochod” jest element o nazwie „opel” a drugim parametrem elementu „opel” jest element „astra”. W ten właśnie sposób zagnieżdżamy elementy.

Listing 19.3 Deklaracja zagnieżdżonych elementów.
Listing 19.3 Deklaracja zagnieżdżonych elementów.

Aby utworzyć nasz nowy plik XML uruchamiamy nasz program. Plik który „zadeklarowaliśmy”, w naszym przypadku plik ma nazwę NaszPierwszyPlikXML.xml, zostanie utworzony w katalogu naszego projektu w podkatalogu bin/Debug. Możemy go wyedytować w notatniku, co obrazuje poniższy rysunek.

Rysunek 19.1 Zawartość pliku „NaszPierwszyPlikXML.xml”.

Rysunek 19.1 Zawartość pliku „NaszPierwszyPlikXML.xml”.
Rysunek 19.1 Zawartość pliku „NaszPierwszyPlikXML.xml”.

Drugim sposobem jest deklarowanie osobno poszczególnych elementów dokumentu XML a dopiero później za pomocą metody Add odpowiednie ich łączenie i zagnieżdżanie. Poniżej przykład takiego podejścia do tworzenia dokumentu XML.

Listing 19.4 Drugi sposób tworzenia dokumentów XML.
Listing 19.4 Drugi sposób tworzenia dokumentów XML.

Zobacz cały kod.

Po uruchomieniu programu (F5) w katalogu naszej aplikacji w podkatalogu bin/Debug, zostanie utworzony plik o nazwie „NaszDrugiPlikXML.xml”. Po otworzeniu naszego pliku w dowolnym edytorze tekstowym np. w notatniku zobaczymy znajomą strukturę naszego pliku XML, co obrazuje poniższy rysunek.

Rysunek 19.2 Zawartość pliku „NaszDrugiPlikXML.xml”.
Rysunek 19.2 Zawartość pliku „NaszDrugiPlikXML.xml”.

C# LINQ to Object

LINQ to Objects

Jak już wspomniałem dla technologii LINQ źródłem danych może być np. kolekcja, czyli obiekt. Aby pokazać zastosowanie tej technologii prześledźmy sobie poniższy przykład.

Dla potrzeb naszego przykładu stworzymy sobie klasę „Produkt”, która będzie przechowywała model naszego obiektu. W naszym przypadku będą to perfumy.

Listing 18.1 Stworzenie klasy Produkt – modelu danych.

Określiliśmy model, to teraz stworzymy kolekcję 5 produktów.

Listing 18.2 Tworzymy kolekcję obiektów o typie Produkt.

I tutaj dochodzimy do stworzenia zapytania w technologii LINQ do naszego źródła danych, w naszym przypadku jest to kolekcja „listaProduktow”.Na początku stworzymy sobie listę wszystkich obiektów z kolekcji.

Listing 18.3 Tworzymy zapytanie LINQ do kolekcji listaProdutkow.

Łączymy wszystko, co zrobiliśmy do tej pory.

Zobacz cały kod.

Poniżej zrzut ekranu po uruchomieniu programu.

LIKQ to Objects
Rysunek 1. Wynik uruchomienia programu.

Operator JOIN

 

Za pomocą technologii LINQ to Objects możemy łączyć zbiory/kolekcje które nie posiadają takiej samej struktury. Do takiej operacji wykorzystujemy operator JOIN. Dla naszych potrzeb z kolekcji listaProdutków stworzymy sobie dwie kolekcje. Pierwsza będzie zawierała id, markę, nazwę i typ, a druga będzie zawierała id, dlaKogo, pojemność i cenę.

Tworzymy pierwszą kolekcję o nazwie perfumy_dane_podstawowe.

Listing 18.5 Tworzymy kolekcję perfumy_dane_podstawowe.

a następnie tworzymy drugą kolekcję perfumy_dane_dodatkowe

Listing 18.6 Tworzymy kolekcję perfumy_dane_dodatkowe.

Mamy więc dwie kolekcje dotyczące tych samych perfum ale zawierające różne dane. Do prawidłowego połączenia obu kolekcji potrzebujemy jakiegoś klucza, bo chcemy aby dane z pól: dlaKogo, pojemność i cena były przyporządkowane do odpowiednich nazw perfum. Aby móc to zrobić w obu kolekcjach powinno znajdować się pole wg którego będzie możliwe wiązanie i w naszym przypadku tym polem (kluczem) jest pole id. Teraz za pomocą tego klucza (pole Id) wykorzystując operator JOIN będę mógł połączyć obie kolekcje w jedną, co prezentuje poniższy listing.

Listing 18.7 Łączenie dwóch kolekcje z wykorzystaniem operatora JOIN.

Słówko wyjaśnienia do powyższego kodu. Po słówku FROM określamy pierwszą kolekcję które będzie podlegała łączeniu. Następnie musimy wskazać kolekcję z którą będziemy chcieli łączyć tą pierwszą ale żeby kompilator nas zrozumiał dodajemy słówko JOIN i po nim określamy drugą kolekcję do łączenia. Jak już wcześniej wspomniałem obie kolekcje łączymy po kluczu którym w naszym przypadku jest pole id i to musimy wpisać w kolejnym kroku. Po słówku ON wskazujemy pole id w pierwszej kolumnie, następnie wpisujemy słówko equals (określające, że oba pola id w obu kolekcjach musza być równe) i wskazujemy pole id w drugiej kolekcji. Po słówku SELECT NEW wypisujemy pola jakie chcemy uwzględnić w nowej kolekcji.

C# LINQ

LINQ

LINQ (ang. Language Integrated Query) w tłumaczeniu na polski znaczy zapytania zbieżne z językiem programowania lub krócej zintegrowany język zapytań.

W dzisiejszym „informatycznym świecie” przeważająca większość aplikacji korzysta z relacyjnych baz danych, są one w zasadzie standardem a co za tym idzie obecność języka SQL. LINQ to nowe podejście do kwestii łączenia ze źródłami danych. Jego funkcjonalność jest znacznie rozszerzona i umożliwia odpytywanie obiektów, jako źródeł danych. Składnia zapytań LINQ przypomina budowanie zapytań w języku SQL ale jednocześnie uniezależnia aplikację od konkretnego źródła danych. Najważniejsze technologie LINQ to LINQ to Objects, LINQ to XML i LINQ to SQL i właśnie na tych zagadnieniach skupimy się w niniejszym kursie.

Poniżej standardowe (niektóre, najczęściej używane) operatory LINQ.

Nazwa operatora Wyjaśnienie działania operatora
Select Operator jest wykorzystywany do pobrania odpowiednich (wybranych przez nas) danych ze źródła danych.
SelectMany Obieranie danych w przypadki relacji jeden-do-wielu np. gdy obiekt który pobieramy z kolekcji posiada inną kolekcję.
Where Operator służy do określenia warunków filtrowania. Jeżeli obiekt ze źródła danych nie pasuje do zadanych reguł filtrowania nie będzie pobrany w zapytaniu.
Count Operator służy do zliczenia elementów kolekcji.
Max Operator służy do otrzymania wartości maksymalnej (np. znalezienie najstarszego pracownika w firmie).
Min Operator służy do otrzymania wartości minimalnej (np. znalezienie najmniej zarabiającego pracownika w firmie).
Sum Operator służy do otrzymania sumy wybranych wartości (np. suma pensji wszystkich pracowników w dziale).
OrderBy Operator służy do sortowania wyników zapytania według zadanego kryterium (np. sortowanie listy pracowników po nazwisku lub po wielkości pensji itp).
First Operator służy do zwrócenia pierwszego elementu kolekcji.
FirstOrDefault Operator służy do zwrócenia pierwszego elementu kolekcji bądź NULL, jeżeli kolekcja jest pusta.
Last Operator służy do zwrócenia ostatniego elementu kolekcji.
LastOrDefault Operator służy do zwrócenia ostatniego elementu kolekcji bądź NULL, jeżeli kolekcja jest pusta.
Single Operator służy do zwrócenia pojedynczego elementu kolekcji (wg zadanych kryteriów).
GroupBy Operator służy do grupowania elementów w zapytaniu.
Join Operator służy do łączenia dwóch zbiorów danych niekoniecznie o takiej samej strukturze encji.
Skip Operator służy do pomijania elementów.
All Operator służy do sprawdzenia czy wszystkie elementy kolekcji spełniają zadany warunek.
Any Operator służy do sprawdzenia czy którykolwiek element kolekcji spełnia zadany warunek.
Contains Operator służy do sprawdzenia czy w wyniku zapytania znajduje się konkretny obiekt.
Concat Operator wykorzystujemy do operacji na zbiorach. Służy do łączenia np. dwóch kolekcji (nowy zbiór zawiera wszystkie elementy jednego i drugiego zbioru; gdy w obu zbiorach istnieją takie same elementy nowy zbiór także będzie zawierał duplikaty).
Distinct Operator służy do usuwania duplikatów (zdublowanych elementów).
Except Operator wykorzystujemy do operacji na zbiorach. Służy do
Union Operator wykorzystujemy do operacji na zbiorach. Służy do łączenia np. dwóch kolekcji z wyłączeniem duplikatów.