17. Metody dostępu do danych - część 1

17. Metody dostępu do danych - część 1

Autor: Piotr Gaszewski

Opublikowano: 6/2/2006, 12:00 AM

Liczba odsłon: 103951

W poprzednim rozdziale zapoznaliśmy się z podstawami języka SQL. Wykorzystując obiekty klas: SqlDataSource i DataView, stworzyliśmy również bardzo prostą aplikację, umożliwiającą wyświetlenie danych w pobranych w bazy w oknie przeglądarki internetowej. Tym razem zaprezentuje kilka sposobów operowania na danych, z poziomu kodu w języku C#. Część przedstawionych w tym miejscu sposobów działania na danych pochodzi z wersji 1.1 platformy Microsoft .NET Framework. Możemy jednak bez problemu stosować je również w aplikacjach tworzonych w ASP.NET 2.0. Specyficzne kontrolki, wprowadzone dopiero w najnowszej edycji środowiska zostaną omówione w rozdziale 18.

Jednym z najważniejszych obiektów wykorzystywanych w komunikacji między aplikacją, a systemem bazodanowym jest SqlConnection. Jak zapewnie się domyślacie obiekt ten reprezentuje połączenie z bazą danych. Jednym z jego najważniejszych parametrów jest ConnectionString. Jest to ciąg znaków, zawierający przeważnie adres serwera bazodanowego, nazwę użytkownika oraz sposób autoryzacji. Jeżeli otworzymy aplikację stworzoną w poprzednim rozdziale definicję tej właściwości możemy łatwo odnaleźć w pliku Web.config.

<connectionStrings>
 
        <add name="NorthwindConnectionString1" connectionString="Data Source=SKYNET;Initial Catalog=Northwind;Integrated Security=True"
 
            providerName="System.Data.SqlClient" />
 
    </connectionStrings>
 
    <system.web>
 

Spróbujmy utworzyć teraz obiekt reprezentujący połączenie w kodzie C#. Znając dokładnie wygląd ConnectionStringa będzie to dziecinnie proste zadanie.

SqlConnection conn = new SqlConnection();
 
conn.ConnectionString = "Data Source=SKYNET;Initial Catalog=Northwind;Integrated Security=True";
 
 
 

Chcąc otworzyć lub zamknąć połączenie z bazą danych wywołujemy metody obiektu conn, o nazwach, odpowiednio: Open() oraz Close().

Kolejnym obiektem, który z całą pewnością przyda się nam do pobierania danych z bazy jest obiekt klasy SqlCommand. Jak sama nazwa wskazuje obiekt ten reprezentuje instrukcje w języku SQL, wykonywaną na bazie danych. Obiekt ten musi posiadać zdefiniowane prawidłowe połączenie (SqlConnection), chcąc wykorzystać go w naszej aplikacji musimy podać również typ oraz treść instrukcji. Poniższy kod zawiera definicję przykładowego obiektu SqlCommand.

SqlCommand objSqlCommand = new SqlCommand();
 
objSqlCommand.Connection = conn;
 
objSqlCommand.CommandType = CommandType.Text;
 
objSqlCommand.CommandText = "SELECT count(*) as ilosc FROM Categories";
 

Jako parametr Connection podajemy zdefiniowane poprzednio połączenie. Typ instrukcji mówi o tym, jakie zapytanie będzie wykonane na serwerze. W powyższym przykładzie treść zapytania definiuje bezpośrednio parametr Text. Do pobrania danych z bazy możemy wykorzystać jednak również na przykład procedurę znajdującą się w bazie danych.

Zapytanie, zawarte we właściwości Text obiektu zwraca ilość wierszy, zawartych w tabeli Categories. Poniższy kod prezentuje, w jaki sposób używając obiektów sqlConnection oraz SqlCommand, wyświetlić wynik zapytania w oknie przeglądarki. Przed wykonaniem tego kodu na formatce internetowej musimy umieścić obiekt klasy Label, o nazwie Label1.

protected void Page_Load(object sender, EventArgs e)
 
{
 
SqlConnection conn = new SqlConnection();
 
conn.ConnectionString = "Data Source=SKYNET;Initial Catalog=Northwind;Integrated Security=True";
 
 
 
SqlCommand objSqlCommand = new SqlCommand();
 
objSqlCommand.Connection = conn;
 
objSqlCommand.CommandType = CommandType.Text;
 
objSqlCommand.CommandText = "SELECT count(*) as ilosc FROM Categories";
 
 
 
conn.Open();
 
this.Label1.Text  = "Liczba wierszy: " + (objSqlCommand.ExecuteScalar()).ToString();
 
conn.Close();
 
} 
 
 

Po otwarciu połączenia z bazą danych wywoływana jest metoda o nazwie ExecuteScalar. Jej zadaniem jest zwrócenie wyniku zapytania. Wynik ten mysi być pojedynczą wartością.

Jeżeli wszystko przebiegło poprawnie, efekt wykonania powyższego kodu powinien wyglądać następująco:

Często zdarza się sytuacja, w której chcemy wykonać na bazie danych operacje, nie zwracającą żadnego konkretnego wyniku. Przykładami takich operacji mogą być: usunięcie, czy też dodanie nowego wiersza do tabeli. Chcąc wykonać taką operację, wykorzystując do tego obiekt objSqlCommand, musimy wywołać metodę ExecuteNonQuery().

@STRONA@ Poniższy kod dodaje nowy wiersz do tabeli Categories, następnie wyświetla na ekranie nową ilość wpisów w tabeli.

public partial class Default2 : System.Web.UI.Page
{
 
    private SqlConnection conn;
 
    private SqlCommand objSqlCommand;
 
 
 
    protected void Page_Load(object sender, EventArgs e)
    {
 
        conn = new SqlConnection();
 
        conn.ConnectionString = "Data Source=SKYNET;Initial Catalog=Northwind;Integrated Security=True";
 
 
 
    }
 
    protected void Button1_Click(object sender, EventArgs e)
    {
 
        objSqlCommand = new SqlCommand();
 
        objSqlCommand.Connection = conn;
 
        objSqlCommand.CommandType = CommandType.Text;
 
        objSqlCommand.CommandText = "INSERT INTO Categories(CategoryName) VALUES ('Nowa Kategoria')";
 
 
 
 
 
        conn.Open();
 
        this.objSqlCommand.ExecuteNonQuery();
 
 
 
        objSqlCommand = new SqlCommand();
 
        objSqlCommand.Connection = conn;
 
        objSqlCommand.CommandType = CommandType.Text;
 
        objSqlCommand.CommandText = "SELECT count(*) as ilosc FROM Categories";
 
 
 
        this.Label1.Text = "Liczba wierszy: " + (objSqlCommand.ExecuteScalar()).ToString();
 
        conn.Close();
 
    }
 
}
 
 

Powyższy przykład ma jednak kilka zasadniczych wad. Nazwa nowej kategorii jest umieszczona na stałe w kodzie. Chcąc dać użytkownikowi aplikacji możliwość definiowania własnych kategorii, dodajmy do formatki pole tekstowe. Użytkownik będzie wpisywał w pole nazwę nowej kategorii, która będzie dodawana do bazy. W tym celu musimy użyć w metodzie parametrów. Zmodyfikowana definicja obiektu SqlCommand1 prezentować się będzie następująco:

objSqlCommand = new; SqlCommand();
 
objSqlCommand.Connection = conn;
 
objSqlCommand.CommandType = CommandType.Text;
 
objSqlCommand.CommandText = "INSERT INTO Categories(CategoryName) VALUES (@CategoryName)";
 
objSqlCommand.Parameters.AddWithValue("@CategoryName", this.TextBox1.Text);
 

Tekst komendy w języku SQL zawiera tym razem parametr o nazwie @CategoryName. Parametr ten możemy wypełnić używając metody właściwości Parameters obiektu objSqlCommand o nazwie AddWithValue. Pierwszy argument metody, to nazwa parametru, natomiast drugi to wartość parametru, pobierana w tym przypadku w pola tekstowego wypełnianego przez użytkownika.

Chcąc wyświetlić na ekranie wynik zapytania zwracającego więcej niż jedną wartość możemy użyć metody ExecuteReader. Zwraca ona obiekt klasy SqlDataReader pozwalający na odczytywanie z bazy danych kolejnych wierszy. Poniższy kod prezentuje przykładowe zastosowanie tej metody.

conn.Open();
 
 
 
                        objSqlCommand = new SqlCommand();
 
                        objSqlCommand.Connection = conn;
 
                        objSqlCommand.CommandType = CommandType.Text;
 
                        objSqlCommand.CommandText = "SELECT CategoryID, CategoryName FROM Categories ORDER BY CategoryID";
 
 
 
                        SqlDataReader reader = objSqlCommand.ExecuteReader();
 
                        this.Label1.Text += "<br>Pobrane wartości: ";
 
                        while (reader.Read())
 
                        {          
 
                                   this.Label1.Text += "<br>" + reader.GetValue(0).ToString();
 
                                   this.Label1.Text += ": " + reader.GetString(1);
 
                        }
 
                        reader.Close();
 
                        conn.Close();
 
 

Każdy programista ASP.NET bardzo szybko zorientuje się, że wyświetlanie wyników zapytania za pomocą obiektu klasy Label nie jest najwygodniejszym sposobem. Do wyświetlenia zawartości tabeli na ekranie możemy wykorzystać znany już obiekt klasy GridView. Przyjrzyjmy się następującemu kodowi:

objSqlCommand = new SqlCommand();
 
objSqlCommand.Connection = conn;
 
objSqlCommand.CommandType = CommandType.Text;
 
objSqlCommand.CommandText = "SELECT * FROM Categories ORDER BY CategoryID";
 
 
 
SqlDataAdapter da = new SqlDataAdapter();
 
DataSet ds = new DataSet();
 
 
 
da.SelectCommand = objSqlCommand;
 
 
 
da.Fill(ds);
 
 
 
this.GridView1.DataSource = ds;
 
this.GridView1.DataBind();
 
 

Obiekt objSqlCommand jest tworzony tak samo, jak w poprzednich przypadkach. Kolejne linijki kodu zawierają jednak dwa nowe obiekty. Pierwszy z nich, klasy SqlDataAdapter, korzysta z objSqlCommand, do wypełnienia drugiego, klasy DataSet. DataSet jest obiektem pozwalającym na operowanie na danych, nie mając cały czas otwartego połączenia z bazą. Wypełnienie obiektu klasy DataSet, następuje w metodzie Fill SqlDataAdaptera.

Do wyświetlenia wyników zapytania używany jest obiekt GridView1. Tym razem jednak jako źródło podajemy mu obiekt klasy DataSet (w poprzednim rozdziale był to SqlDataSource). W celu wyświetlenia w oknie przeglądarki wyników naszego zapytania musimy użyć metody DataBind.

Jak wykorzystać Copilot w codziennej pracy? Kurs w przedsprzedaży
Jak wykorzystać Copilot w codziennej pracy? Kurs w przedsprzedaży

Wydarzenia