UWAGA! Promocja dla firm - MICROSOFT OFFICE 365  na 12 miesiecy ZA DARMO! Tylko na CentrumXP.pl!
Wielka promocja Office 365 na CentrumXP.pl!
Do góry Skomentuj

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

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

Autor: Piotr Gaszewski Opublikowano: 2 czerwca 2006 Odsłon: 78 308

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().

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.

Zobacz również

Komentarze

Mam pewne zastrzezania do tego kodu. Wklejam go do mojego programu, mam swoja baze danych, robie wszystko analogicznie jak tutaj. Kompilator wyswietla blad przy: this.objSqlCommand.ExecuteNonQuery(); O co chodzi?
Kamil, 26 sierpnia 2007, 15:19
bo to jest do polecen niezwracjacych danych - jak insert, delete, itp tutaj uzywasz ExecuteScalar - 1 wiersz i kolumne wyniku lub ExecuteReader - wiele kolumn i wierszy
izox, 1 października 2007, 17:34
za wczesnie chyba odpowiedzialem ;p cos nieprzytomny jestem. w kazdym badz raze kod w przykladach jest prawidlowy - to czy uzyjemy tam this czy nie niepowinno robic roznicy, ale powinna byc stala koncepcja nazewnictwa.
izox, 1 października 2007, 17:54
Jak komuś cos nie działą to proszę spróbować tak zdefiniować: SqlConnection Polaczenie = new SqlConnection("Data Source=SIMON;Initial Catalog=Northwind;Integrated Security=True"); SqlCommand objSqlCommand = new SqlCommand(); objSqlCommand.Connection = Polaczenie; objSqlCommand.CommandType = CommandType.Text; objSqlCommand.CommandText = "SELECT count(*) as ilosc FROM Categories";
Simon, 6 października 2007, 17:54
Dlaczego na str. 3, dwa razy twozymy ten sam obiekt "objSqlCommand = new SqlCommand();" nawed jezeli chemy stworzyc drugi obiekt to dlaczego o takiej samej nazwie i dlaczego tworzymy go po otwarci polaczenia "conn.Open();", a nie przed (bo przeciez jak i tak tworzymy drugi obiekt to po nadaniu mu innej nazwy mozna wywolac tylko same metody "ExecuteNonQuery(); ExecuteScalar(); wewnatrz polaczenia conn.Open();")?

blacky, 7 lutego 2009, 15:43
"Dlaczego na str. 3, dwa razy twozymy ten sam obiekt "objSqlCommand = new SqlCommand()" blacky to proste bo jeden służył do pobierania a drugi do wkładania danych.
Ja mam ine pytanie czy, jeżeli typ danych w bazie dajmy nato System.Typecode jest int32 to czy polecenie :
objSqlCommand.Parameters.AddWithValue("@CategoryName", this.TextBox1.Text);
samo  domyśli się że to jest int a nie string?, w sumie wartość this.TextBox1.Text jesst zawsze ptypu string?
Może bezpieczniej jest:
  FormParameter dana = new FormParameter();&lt;br />  dana.Name = kolumny+i.ToString();&lt;br />  dana.Type = TypeCode.Int32;&lt;br />  dana.FormField = wartości;&lt;br />  dana.DefaultValue = "0";&lt;br />  this.Baza.InsertParameters.Add(dana);&lt;br /> this.Baza.InsertCommand = string.Format("INSERT INTO [{0}"> ({1}) VALUES ({2})",tabela,instertInto ,values);
 this.Baza.Insert();
???

Daro, 9 lutego 2009, 12:59
Pytanie Daro 9 lutego 2009, 12:59 nieaktualne jeśli dana.Type będzie TypeCode.String, to nieważne jaki typ danych będzie w bazie, wstawi się dobrze, pod warunkiem że przekazane dane odpowiadaja możliwym wartościom zdefinowanym w kolumnach.

daro, 9 lutego 2009, 17:56
jesli sie nie laczy
System.Data.SqlClient.SqlConnection polaczenie = new System.Data.SqlClient.SqlConnection();
&lt;br />  polaczenie.ConnectionString = "Data Source=X-5C8LDDHC9ZSEI\\SQLEXPRESS ;Initial Catalog=Filmy ;Integrated Security=True ";

Ender , 12 maja 2009, 09:52
Pozwole sobie dodać iż trzeba dodać na samej górze linijkę. "using System.Data.SqlClient;" Wówczas możemy korzystać z funkcji opisanych w tym artykule.
Marcin, 19 sierpnia 2010, 18:41
Jeśli ktoś korzysta z Visual Studio 2010 (jak ja) linie: objSqlCommand.CommandType = CommandType.Text; musi zamienić na: objSqlCommand.CommandType = new System.Data.CommandType(); wtedy działa jak należy.
Defice, 12 grudnia 2011, 09:59

Dodaj swój komentarz

Zasady publikacji komentarzyZasady publikacji komentarzy

Redakcja CentrumXP.pl nie odpowiada za treść komentarzy publikowanych na stronach Portalu
i zastrzega sobie prawo do usuwania wypowiedzi, które:

  • zawierają słowa wulgarne, obraźliwe, prowokujące i inne naruszające dobre obyczaje;
  • są jedynie próbami reklamowania stron internetowych (spamowanie poprzez umieszczanie linków);
  • przyczyniają się do złamania prawa bądź warunków licencyjnych oprogramowania (cracki, seriale, torrenty itp.);
  • zawierają dane osobowe, teleadresowe, adresy mailowe lub numery GG;
  • merytorycznie nie wnoszą nic do dyskusji lub nie mają związku z tematem komentowanego newsa, artykułu bądź pliku.

Autor:

Komentarz:

Dodaj komentarz