Dane są wszędzie, a posiadanie ich I umiejętne wykorzystanie daje przewagę nad konkurencją. Warto więc z nich korzystać w naszych programach. W nauce programowania przychodzi taki moment, że już nie wystarczy zapisywanie pliku txt z informacją. Nawet książka Head First C# zaczyna się od programu wykorzystującego dane. Pracując jako programista nie da się uniknąć aplikacji współpracujących z różnymi bazami danych.
Microsoft wraz z .NET Framework dostarcza świetne narzędzie o nazwie ADO.NET. Jest to bogaty zbiór składników, które umożliwiają komunikację z bazami danych. Pamiętam jak stworzyłem pierwszą swoją aplikację, która połączyła się do bazy i tę radość, jak mi się to udało. Często jest też to aplikacja zaliczeniowa na studiach, więc tym bardziej wpis będzie użyteczny.
Zacznijmy od początku. Stwórzmy sobie klasę, która będzie reprezentowała tabelę w bazie danych:

Następnie tworzymy klasę odpowiedzialną za manipulację danymi. Aby skorzystać z ADO.NET, należy dodać using do biblioteki System.Data i System.Data.SqlClient. Dodajemy konstruktor, który jako parametry będzie przyjmował adres serwera bazy danych i nazwę bazy danych. Kolejny konstruktor będzie przyjmował dodatkowo login i hasło. Pozwoli to nam tworzyć obiekt połączenia z bazą danych w zależności od tego, czy korzystamy z Windows Authentication, czy SQL Server Authentication. Musimy jeszcze dodać Connection String, który będziemy tworzyli w konstruktorze. Jest to konfiguracja połączenia do bazy danych, dzięki której ADO.NET będzie w stanie nas połączyć.

Teraz musimy napisać metodę, która będzie wykonywała zapytanie w bazie danych i zwracała wynik SELECTa w postaci kolekcji wierszy.
Tworzymy obiekt SqlConnection, który będzie odpowiedzialny za połączenie z bazą danych. Z racji tego, że ma on zaimplementowany interfejs IDisposible i metodę Dispose(), możemy utworzyć go korzystając z using. Jako parametr wejściowy do konstruktora przekazujemy naszego Connection Stringa.
Teraz tworzymy obiekt klasy SqlCommand, który wykona nasze zapytanie na wcześniej utworzonym połączeniu. Nadajemy mu typ tekstowy: CommandType.Text. Do konstruktora przekazujemy nasze zapytanie do bazy i obiekt odpowiedzialny za połączenie z bazą danych.
Następnie tworzymy obiekt DataSet, do którego przekażemy odebrane dane. Ma on bardzo dużo możliwości, ale zazwyczaj wykorzystuje się tylko te podstawowe (polecam poczytać trochę o tym obiekcie w Internecie).
Kolejnym krokiem jest stworzenie obiektu SqlDataAdapter, który odbierze dane z bazy. Korzystając z metody Fill na tym obiekcie i jako parametr podając wcześniej utworzony obiekt DataSet nasze dane zostają pobrane z bazy danych i „wrzucone” do obiektu dataSet.
W ostatnim kroku pobieramy z obiektu dataSet kolekcję tabel pobranych z bazy danych i zwracamy je jako wynik działania naszej metody.

Ostatnim krokiem jest wykorzystanie wyżej stworzonej metody. W tym celu piszemy metodę publiczną, która wykona zapytanie i zwróci nam kolekcję obiektów klasy Osoba.

W pierwszym kroku korzystamy z przygotowanej metody i pobieramy z bazy danych kolekcję wierszy. Teraz wystarczy zrobić pętlę foreach, która przeiteruje nam naszą kolekcję wierszy. Trzeba pamiętać, aby podać typ danych (DataRow), ponieważ korzystając z var zamiast otrzymywać obiekt DataRow otrzymamy obiekt typu ogólnego Object. W pętli tworzymy nowe obiekty z przedmiotami pobranymi z bazy danych. Można to zrobić na dwa sposoby: 1. dataRow[„NazwaKolumny”] 2. dataRow[numerKolumny] Zalecane jest stosowanie sposobu nr. 1, ponieważ przy dużej ilości pobieranych kolumn łatwo pomylić numer kolumny, dodatkowo zabezpieczamy się przed błędem związanym ze zmianą zapytania np. jeśli podamy nazwy kolumn w innej kolejności, to sposób 1 będzie nadal szukał nazw kolumn, a sposób 2 nie odniesie się do zmian i zamieniając kolejnością siłę z mocą stworzymy obiekt z błędnymi danymi. Wszystkie wyciągnięte dane z DataRow są typu Object, dlatego należy je przekonwertować na odpowiednie typy.
Gdy mamy przygotowaną już metodę, możemy z niej skorzystać i pobrać listę osób:

Są tu dwie niewyjaśnione rzeczy: znak $ w konstruktorach i tajemnicze yield return z którym powiązany jest interfejs IEnumerable. Są to jednak bardziej złożone tematy, więc wyjaśnię je w kolejnych wpisach.