ADO.NET SqlDataAdapter cz.1 – Wstęp

 

Wszystkie dotychczas omawiane przeze mnie elementy ADO.NET były wprowadzeniem do przedstawienia klasy SqlDataAdapter. Klasa ta jest, można powiedzieć, opakowaniem zawierającym omawiane elementy, co sprawia, że jest ona szczególnie istotna z punktu widzenia łatwego zarządzania danymi pochodzącymi z bazy. Wreszcie klasa ta powinna być szczególnie interesująca dla osób programujących w ASP.NET. Znany z tej technologii obiekt SqlDataSource reprezentujący bazę danych dla kontrolek wykorzystujących z niej dane (data-bound controls) posiada wiele cech wspólnych z obiektem SqlDataAdapter (co do genezy obiektu SqlDataSource i tego jak został on zaimplementowany na obecnym stanie wiedzy nie jestem w stanie się wypowiedzieć). Zacznijmy zatem omawianie klasy SqlDataAdapter.

Kiedy powinien być wykorzystany obiekt typu SqlDataAdapter? W poprzednich przykładach pokazywałem jak można pobrać dane z bazy, a następnie wykorzystać je do zainicjalizowania kontrolki w postaci listy wyświetlającej pobrane elementy. Czasem jednak użytkownik może chcieć przetwarzać pobrane dane, a następnie zsynchronizować je z istniejącą bazą. Wszystko to oczywiście musi odbywać się w maksymalnie prosty sposób. Właśnie do tego celu doskonale nadaje się obiekt typu SqlDataAdapter. Czym jest tak właściwie SqlDataAdapter? Z racji niezręczności tłumaczeniowej pozwole sobie przytoczyć tu angielskojęzyczną definicję: “The SqlDataAdapter class acts as a bridge between the connected and disconnected halves of the ADO.NET object model”. W tym miejscu warto przytoczyć wspomniany model (z racji tego, że nie mam teraz dostępu do zasad cytowania posiadanego przeze mnie źródła zamieszczam opracowany przeze mnie bardzo, bardzo uproszczony model):

adonet modeljpg

Obiekt typu SqlDataAdapter znajduje się w grupie oznaczonej na rysunku jako Data Providers (podobnie jak SqlCommand, SqlDataReader). Obiekty należące do tej grupy mogą komunikować się z fizycznie istniejącą bazą danych. Dane pochodzące z bazy mogą być następnie wykorzystane przez np. kontrolki ASP.NET (na rysunku to Data Consumers). Dane mogą być także przechowywane w obiekcie DataSet, który pełni w tym przypadku rolę cache’u. Jak widać na rysunku obiekty należące do grupy Data Consumers mogą wykorzystywać dane pochodzące z bazy również za pośrednictwem DataSet. Warte podkreślenia jest to, że sam obiekt DataSet nie ma możliwości komunikacji z bazą danych. Od tej pory wszelkie operacje dodawania nowych danych, aktualizowania, kasowania, wykonywane będą na obiekcie DataSet. Następnie tak przetworzone dane przekazywane będą do obiektu SqlDataAdapter, który spowoduje odpowiednie uaktualnienia w bazie danych.

Tworząc obiekt SqlDataAdapter chcielibyśmy operować na danych, które należy uprzednio pobrać. Z tego powodu najczęściej używanymi konstruktorami będą te, które wykorzystują nazwę ciągu znakowego z zapytaniem do bazy. Można zatem skorzystać z następującego konstruktora:

SqlDataAdapter da = new SqlDataAdapter(strSql, strConn);

W kodzie tym zmienna strSql to obiekty typu string zawierający treść zapytania wykorzystującego polecenie SELECT, natomiast strConn to również obiekt typu string, ale zawierający tzw. connectionString. W celu odebrania danych należy najpierw utworzyć obiekty DataSet, a następnie wypełnić go danymi z bazy:
 
DataSet ds = new DataSet();
da.Fill(ds);

Widać więc, że nie trzeba w tym przypadku tworzyć nowego połączenia, otwierać go, pamiętać o zamknięciu lub zastosowaniu bloku using. Omijamy tworzenie obiektów odczytujących dane, niepotrzebne są iteracje pobierające kolejne wiersze ze strumienia itp. Obiekt SqlDataAdapter sam dba o utworzenie odpowiedniego połączenia, wykonanie niezbędnych operacji i zamknięcie połączenia. Zawsze możemy jednak chcieć wykonać pewne czynności samemu w celu usprawnienia gotowych mechanizmów. Jeśli chcielibyśmy utworzyć wiele obiektów typu SqlDataAdapter to w podany powyżej sposób każdy z nich otwierał by nowe połączenie na własny użytek. Czasem na takie marnotrawstwo zasobów nie można sobie pozwolić i polecane jest inne rozwiązanie. Sednem tego rozwiązania jest ręczne utworzenie połączenia i jego otwarcie, pozwolenie obiektowi SqlDataAdapter na skorzystanie z niego i ręczne zamknięcie na koniec tego połączenia. W ten sposób ograniczana jest liczba wykorzystywanych połączeń. Dla tego typu operacji klasa SqlDataAdapter udostępnia inny konstruktor, przyjmujący jako parametr nie ciąg znakowy z connectionString-iem, lecz obiekt typu SqlConnection. Przykładowy kod mógłby wyglądać w tym przypadku następująco:
 
using(SqlConnection cn = new SqlConnection())
{
    try
    {
        cn.Open();
        SqlDataAdapter da = new SqlDataAdapter(strSql, cn);
        SqlDataAdapter da2 = new SqlDataAdapter(strSql2, cn);
        ...
    }
    catch(Exception ex)
    {
        //Implement
    }
}

W kolejnej części (częściach) omówione zostaną bardziej skomplikowane mechanizmy związane z klasą SqlDataAdapter.
Reklamy

Skomentuj

Wprowadź swoje dane lub kliknij jedną z tych ikon, aby się zalogować:

Logo WordPress.com

Komentujesz korzystając z konta WordPress.com. Log Out / Zmień )

Zdjęcie z Twittera

Komentujesz korzystając z konta Twitter. Log Out / Zmień )

Facebook photo

Komentujesz korzystając z konta Facebook. Log Out / Zmień )

Google+ photo

Komentujesz korzystając z konta Google+. Log Out / Zmień )

Connecting to %s

%d blogerów lubi to: