ADO.NET SqlDataAdapter cz.2 – Properties

 

W poprzedniej części dotyczącej obiektu SqlDataAdapter przedstawiłem ogólny zarys tego, czym jest ten obiekt, jak go utworzyć oraz jak za jego pomocą pobrać dane z bazy. Omówiłem też kilka jego podstawowych cech. W niniejszym poście postaram się przedstawić podstawowe zastosowanie obiektu typu SqlDataAdapter.

Zacznijmy od przypomnienia tego, jak to było na początku. Do pobrania danych z bazy wykorzystywany był obiekt typu SqlCommand. Dane te mogły być następnie w jakiś sposób wyświetlone użytkownikowi lub zapisane. Jeśli chcieliśmy wysłać jakieś dane do bazy, dokonując jej uaktualnienia, również należało utworzyć obiekt typu SqlCommand tym razem z odpowiednim poleceniem wstawiania, aktualizacji, czy też kasowania danych. SqlDataAdapter wyróżnia się tym, że posiada on m.in. cztery właściwości, przechowujące obiekty typu SqlCommand, po jednym dla każdej operacji. Są to więc właściwości:

  • SelectCommand
  • InsertCommand
  • UpdateCommand
  • DeleteCommand

Każdy z wymienionych obiektów może zawierać zwykłe zapytania, jak również nazwę procedury składowanej. SqlDataAdapter pozwala zatem na komunikację w obie strony – pobieranie danych z bazy oraz ich wysyłanie do bazy. Dodatkowo, w tym drugim przypadku, dane nie muszą być od razu wysłane do bazy, a mogą one poczekać na odpowiedni do tego moment. Stosowane przy tym jest następujące rozwiązanie:

...
SqlDataAdapter da = new SqlDataAdapter(strSql, strConn);
DataSet ds = new DataSet();

//Fetch results from database
da.Fill(ds);

DataRow row = ds.Tables[0].NewRow();//return a row with a schema from table
row["City"] = CityTextBox.Text;
row["Street"] = StreetTextBox.Text;

ds.Tables[0].Rows.Add(row);
...//Add more data to table

//Submit changes
da.Update(ds);
...

W powyższym przypadku zapytanie inicjalizujące obiekt DataSet miało postać:

string strSql = "SELECT Addr_Id, City, Street FROM dbo.Addresses;";

Naszym zbiorem danych DataSet jest więc tabela o trzech kolumnach wypełniona danymi pochodzącymi z utworzonej wcześniej tabeli w bazie danych. Do tak utworzonej tabeli wpisywane są dane, które użytkownik przekazał za pomocą formularza w postaci pól tekstowych. W tym celu należy dodać nowy wiersz do tabeli znajdującej się w obiekcie DataSet. Aby miał on taką strukturę (takie same kolumny) jak dotychczas istniejące wiersze w tabeli należy skorzystać z metody NewRow() wywoływanej na rzecz tabeli (w tym przypadku do DataSet pobrane zostały jedynie wyniki z jednego zapytania stąd odwołanie poprzez indeks 0). Następnie poprzez odwołanie do odpowiednich kolumn wstawiane są dane do wiersza, który ostatecznie jest dodawany do tabeli. Operacja taka może być wykonana wiele razy. Pozwala na pracę z danymi bez konieczności komunikacji z bazą danych. Zatwierdzenie wprowadzonych zmian, czyli synchronizacja obiektu DataSet z bazą następują dopiero po wywołaniu metody Update() z podaniem aktualizowanego zbioru danych (oczywiście po zapewnieniu, że istnieje przypisany obiekt do właściwości np. InsertCommand).

Załóżmy, dla uproszczenia, że chcemy nowe dane wysłać do bazy tuż po ich wstawieniu do obiektu DataSet. W pierwszym zamieszczonym kodzie, w miejscu symbolicznie zapisanej 16 linii da.Update(ds), powinien znaleźć się następujący fragment kodu:

...
string query = "INSERT INTO dbo.Addresses (City, Street) VALUES (@City, @Street);";

using (SqlConnection cn = new SqlConnection(BuildConnectionString()))
{
    //Usage explained in one of earlier posts
    cn.Open();
    SqlCommand cmd = new SqlCommand(query, cn);

    //Binding columns from DataSet as InsertCommand parameters     
    cmd.Parameters.Add("@City", SqlDbType.VarChar, 30, "City");
    cmd.Parameters.Add("@Street", SqlDbType.VarChar, 30, "Street");

    //Assign object to property
    da.InsertCommand = cmd;
    da.Update(ds);
}

Tworzony jest w nim obiekty typu SqlCommand z treścią zapytania. W kolejnych liniach następuje dodanie nowych parametrów do zapytania. Pierwsza wartość to nazwa zmiennej w zapytaniu, druga to typ jaki będzie wstawiany do bazy, trzecia to rozmiar dla typu, natomiast ostatnia to nazwa kolumny w DataSet, z której będą wybierane pola przypisywane odpowiedniej zmiennej. Przypisanie tak utworzonego obiektu do właściwości InsertCommand sprawia, że treść podanego zapytania z podanymi parametrami będzie wykonywana zawsze, gdy zajdzie potrzeba wstawienia danych do bazy, czyli wtedy, gdy zbiór DataSet będzie posiadał więcej wierszy niż tabela/tabele z której dane zostały pobrane.
 
Analogicznie, przed synchronizacją z bazą, możliwe jest wstawienie liczby wierszy większej niż jeden. Warto zwrócić uwagę, że z bazy pobrane zostały trzy wiersze, a dane pochodzące z pól tekstowych wstawiane są tylko do dwóch kolumn, z pominięciem kolumny o nazwie Addr_Id, w której w tabeli znajdującej się w bazie założony został klucz główny. Pomimo tego, że do DataSet wstawiane są jedynie wartości w dwóch kolumnach, a Addr_Id pozostaje pusta, to po wykonaniu zapytania w bazie danych oczywiście bez problemu wstawiana jest poprawna wartość. Więcej o kluczach, schematach i ograniczeniach w kolejnych odsłonach.

Dodaj komentarz