ADO.NET proste zapytania do bazy + ASP.NET

 

W poprzednich dwóch odsłonach informacje pobrane z bazy danych wyświetlane były na wyjściu diagnostycznym. Nadszedł czas na przedstawienie bardziej praktycznego rozwiązania, które wymaga interakcji ze strony użytkownika. W tym celu wykorzystana zostanie kontrolka ASP.NET, jaką jest CheckBoxList. W przedstawionym przeze mnie przykładzie taka lista zapełniana jest opcjami pochodzącymi z przygotowanej bazy danych. Jej elementy zawierają pola pochodzące z kolumny LoginName z tabeli SimpleLogins. Użytkownik, po zaznaczeniu wybranych przez siebie pozycji, a także kliknięciu w odpowiedni przycisk, otrzymuje informację zwrotną o swoim wyborze. Zatem do dzieła…

Po naciśnięciu przez użytkownika przycisku o nazwie “insertDataIntoTableButton” wykonywany jest następujący kod:

protected void insertDataIntoTableButton_Click(object sender, EventArgs e)
{
    //Select all logins from table
    string strSql = "SELECT LoginName FROM SimpleLogins";
    List<string> loginsList = new List<string>(2);//initial capacity set to 2
    int ordinalColumn = -10;//bad column number at start

    using (SqlConnection cn = new SqlConnection(BuildConnectionString()))
    {
        try
        {
            cn.Open();

            using (SqlCommand cmd = new SqlCommand(strSql, cn))
            {
                try
                {   
                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        try
                        {
                            ordinalColumn = reader.GetOrdinal("LoginName");

                            while (reader.Read())
                            {
                                loginsList.Add(reader.GetString(ordinalColumn));
                            }

                        }
                        catch (Exception ex)
                        {
                            //reader exception implement
                        }
                        finally
                        {
                            loginsList.TrimExcess();
                            reader.Close();
                        }

                    }

                }
                catch (Exception ex)
                {
                    //implement
                }

            }
        }
        catch (Exception ex)
        {
            //implement
        }

    }

    //Connection closed - data in List named loginsList
    populateCheckBoxList(loginsList);
}

Omówmy teraz to, co zostało zawarte w powyższym kodzie. Dane pobrane z bazy zapisywane są w obiekcie typu List<string>, przy przedstawionym użyciu metody ExecuteReader() nie znamy bowiem liczby zwróconych wierszy z bazy, potrzebujemy zatem obiektu, który zmieniał będzie dynamicznie swój rozmiar. W porównaniu do poprzednich przykładów zmienił się nieco sposób odczytu danych. Jak zostało to w poprzednich postach wspomniane, wykorzystanie metod zwracających określony typ danych wymaga podania jako argumentu numeru odczytywanej kolumny. Zdarzyć się może jednak taka sytuacja, w której nie będziemy znali położenia w zapytaniu tej kolumny. Obiekt typu SqlDataReader posiada pomocną metodą, która pozwala ominąć to ograniczenie. Mowa tutaj o metodzie GetOrdinal(). Spójrzmy na poniższy fragment przedstawionego wcześniej kodu:

try
{
    ordinalColumn = reader.GetOrdinal("LoginName");

    while (reader.Read())
    {
        loginsList.Add(reader.GetString(ordinalColumn));
    }
}

Argumentem metody GetOrdinal() jest nazwa kolumny. Jej zadaniem jest ‘przetłumaczenie’ nazwy kolumny na jej numer porządkowy. Warto zaznaczyć, że taka operacja, w przypadku wykonania jej przed odczytem danych ze strumienia, może znacząco przyśpieszyć sam proces odczytu, szczególnie dla dużej ilości danych. Znając już numer odpowiedniej kolumny można przystąpić do zapisania odczytanych danych na utworzonej wcześniej liście.

Po zamknięciu połączenia wykonywana jest metoda, której zadaniem jest powiązanie obiektu typu CheckBoxList z wypełnioną przez nas danymi listą. Metoda ta została zaimplementowana następująco:

/// <summary>
/// Populates CheckBoxList with options to select
/// </summary>
private void populateCheckBoxList(List<string> cbl)
{
    try
    {
        //Bind data from loginsList to CheckBoxList1
        this.CheckBoxList1.DataSource = cbl;
        this.CheckBoxList1.DataBind();
    }
    catch (Exception ex)
    {
        //implement
    }
}

Związanie źródła danych z kontrolką następuje poprzez przypisanie go do właściwości DataSource. Faktyczne związanie następuje jednak dopiero po wywołaniu metody DataBind(), więc nie można o nim zapomnieć.

Załóżmy teraz, że wybrane opcje z CheckBoxList-y, nie znając ich wcześniejszego pochodzenia, chcemy wyświetlić użytkownikowi na innej stronie w przyjemnej formie, dodatkowo po naciśnięciu przycisku. Utworzenie i wypełnienie przygotowanej listy może przyjąć następującą postać:

List<string> myList = new List<string>(2);
           
if (CheckBoxList1.Items != null)
{
   foreach (ListItem elem in CheckBoxList1.Items)
   {
       if (elem.Selected)
       {
           myList.Add(elem.Value);
       }
   }
}

Najprostszym sposobem przekazania wszystkich wartości znajdujących się na liście byłoby przekazanie jej w całości do innej strony. Nie rozważając w tej chwili skuteczności takiego rozwiązania ASP.NET umożliwia przekazanie takiego obiektu poprzez stan sesji – Session State. (z racji posiadanej przeze mnie prawie wyłącznie anglojęzycznej literatury nie jestem pewien polskiego odpowiednika – kiedyś w php wiem, że funkcjonowało określenie zmienne sesyjne w odniesieniu do tak przekazywanych zmiennych). Przypisanie obiektu do zmiennej sesyjnej odbywa się poprzez wykorzystanie indeksów z odpowiednim ciągiem znakowym, czyli:
Session["myList"] = myList;
Przekierowanie na inną stronę może być natomiast zrealizowane w następujący sposób:
Server.Transfer("Details.aspx");
Zmienne sesyjne na nowej stronie są odczytywane również z wykorzystaniem indeksów. Tym razem jednak należy dokonać operacji rzutowania na określony typ. Uprzednio należy sprawdzić, czy dana zmienna istnieje w sesji. O ile próba odczytania danych ze zmiennej, która nie istnieje nie powoduje wyrzucenia wyjątku, o tyle jeśli spróbujemy iterować po obiekcie, do którego została ona nieświadomie przypisana, można już otrzymać wyjątek. Uprzednio dobrze jest więc sprawdzić, czy dana zmienna sesyjna istnieje:
if (Session["myList"] != null)
{
    List<string> myList = (List<string>)Session["myList"];
    foreach (string elem in myList)
    {
        TextBox1.Text += elem + Environment.NewLine;
    }
}

Reklamy

2 Responses to ADO.NET proste zapytania do bazy + ASP.NET

  1. vebaspect says:

    Tak abstrahując od tematu wpisu: Poszukaj może minimalnie szerszego szablonu, bo strasznie ucina zamieszczany kod. 🙂
    Pozdrowienia!

Skomentuj

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

Logo WordPress.com

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

Zdjęcie z Twittera

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

Zdjęcie na Facebooku

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

Zdjęcie na Google+

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

Connecting to %s

%d blogerów lubi to: