ASP.NET i Web Matrix – część 5

Transkrypt

ASP.NET i Web Matrix – część 5
Obsługa baz danych z użyciem ADO.NET
4. Obsługa baz danych w środowisku Web Matrix
Środowisko ASP.NET Web Matrix umożliwia zarówno połączenie z istniejącą bazą danych,
jak również utworzenie nowej bazy danych. Założysz teraz na swoim komputerze nową
bazę danych o nazwie bank. Będzie ona wykorzystywana już do końca kursu.
Warto nadmienić, że w poprzedniej wersji środowiska (0.5) była tylko możliwość dostępu
do baz danych MS SQL Server (w okresie, gdy istniała tylko wersja 1.0 .NET Framework).
Od wersji 0.6 w środowisku Web Matrix istnieje możliwość obsługi baz danych w formacie
MS Access (wiąże się to też z dostępnością wersji 1.1 .NET Framework).
Tworzenie bazy danych
1. Pod okienkiem projektu, po prawej stronie ekranu znajdują się trzy zakładki:
Workspace, Data oraz Open Windows. W celu rozpoczęcia pracy z bazą danych
przełącz się na zakładkę Data.
2. Kliknij w przycisk Add Database Connection znajdujący się na pasku narzędzi Data.
3. Na ekranie pojawi się okno dialogowe Add New Project. Wskaż pozycję Access
Database i kliknij w OK.
4. Na ekranie pojawi się teraz okno dialogowe Connect to Database.
5. Kliknij w łącze Create a new database znajdujące się u dołu okna dialogowego
Connect to Database.
6. Na ekranie pojawi się okno dialogowe Create New Access Database. W katalogu
głównym projektu, obok katalogów ascx, bank, klient, style i temp, stwórz podkatalog
dane. Wejdź do środka i w polu nazwy pliku bazy danych wpisz bank.mdb,
a następnie kliknij w OK.
7. Środowisko ASP.NET Web Matrix utworzy nową bazę danych bank. W oknie
Workspace pojawi się widok drzewa, zawierający węzeł nadrzędny o nazwie
bank.mdb (wraz ze ścieżką do katalogu zawierającego plik bazy danych). Rozwiń ten
węzeł nadrzędny i kliknij w węzeł o nazwie Tables w widoku drzewa okna Data,
a następnie kliknij w przycisk New Database Object znajdujący się na pasku narzędzi
Data.
8. Na ekranie pojawi się okno dialogowe Create New Table.
9. W polu Name of the new table wpisz klienci.
10. Stworzona tabela posiada jedną domyślną kolumnę. Zamień ją na klucz główny
według wskazówek z punktów 11 i 12.
11. W polu Name, które znajduje się w dolnym obszarze okna, wpisz id.
12. Z listy rozwijanej DataType wybierz pozycję AutoNumber.
1
Obsługa baz danych z użyciem ADO.NET
13. Zmień w polach InPrimaryKey oraz IsUniqueKey wartość na True.
14. Klikając w przycisk New, znajdujący się w lewym górnym rogu okna, możesz dodawać
kolejne kolumny. Stwórz w ten sposób kolumny w tabeli klienci, jak pokazano
poniżej:
Nazwa kolumny (Name)
id
imie
nazwisko
adres
kod
miasto
kraj
domowy
komorkowy
email
Nazwa właściwości
DataType
AllowNulls
InPrimaryKey
IsUniqueKey
DataType
Size
AllowNulls
DataType
Size
AllowNulls
DataType
Size
AllowNulls
DataType
Size
AllowNulls
DataType
Size
AllowNulls
DataType
Size
AllowNulls
DataType
Size
AllowNulls
DataType
Size
AllowNulls
DataType
Size
AllowNulls
Wartość właściwości
AutoNumber
False
True
True
Text
50
False
Text
80
False
Text
60
False
Text
10
False
Text
40
False
Text
30
False
Text
25
True
Text
25
True
Text
50
True
15. Na dole okna, w którym były tworzone kolumny tabeli znajdują się zakładki Design
oraz Data. Możesz teraz dokonać edycji zawartości stworzonej tabeli, wskazując
zakładkę Data. Pojawi się pytanie, czy należy zapisać zmiany w schemacie tabeli
— należy na nie odpowiedzieć twierdząco.
Uwaga: Od momentu, gdy do tabeli zostaną wprowadzone jakiekolwiek dane, nie
można już zmieniać jej schematu. Dlatego przed stworzeniem początkowych danych
upewnij się, czy kolumny tabeli są zgodne z powyższą specyfikacją.
16. Do tabeli klienci wpisz przynajmniej cztery nowe wiersze danych. Pamiętaj, że musisz
podać wartości dla wszystkich kolumn, które mają właściwość AllowNulls równą
False.
Uwaga: Aby zapamiętać zmieniony wiersz w bazie danych, naciśnij klawisz Enter lub
zaznacz inny wiersz w siatce danych.
Uwaga: Kolumna id ma domyślnie ustawione właściwości IdentitySeed oraz
IdentityIncremenet (automatyczne numerowanie od 1 z krokiem 1). Baza danych
2
Obsługa baz danych z użyciem ADO.NET
automatycznie wylicza i przypisuje nową wartość polu typu AutoNumber w momencie
zapisywania wiersza w bazie danych.
Uwaga: Siatka danych wyświetlana w oknie Data umożliwia tylko odczytywanie
wartości pól typu AutoNumber.
Uwaga: Aby wyświetlić widok definicji tabeli, w trakcie edycji kliknij w zakładkę
Design, znajdującą się u dołu okna dialogowego. Nie możesz zmienić definicji tabeli,
jeśli znajdują się w niej jakiekolwiek dane.
17. Możesz zamknąć okno edycji tabeli. Dane w bazie zostaną automatycznie zapisane.
Najprostszy odczyt danych z bazy
Jeśli chodzi tylko o szybkie wyświetlenie zawartości całej tabeli, to w środowisku Web
Matrix jest to wyjątkowo proste. Wystarczy przeciągnąć wybraną tabelę na stronę, aby
automatycznie pojawiły się tam dwie kontrolki umożliwiające przeglądanie zawartości
tabeli. Należy jednak podkreślić, że są to kontrolki dostarczane ze środowiskiem Web
Matrix. Ich zadaniem jest uproszczenie budowy stron w tym środowisku, nie są to
natomiast kontrolki standardowe ASP.NET (które będą omówione już niebawem).
Rysunek 4. Wygląd strony po przeciągnięciu na nią tabeli klienci
Jedna ogólna uwaga jest następująca — Web Matrix niezbyt uważnie obsługuje
dyrektywy plików włączanych, umieszczone w kodzie HTML. Warto więc co jakiś czas
zaglądać, czy ostatnio dokonane zmiany nie spowodowały jakichś katastrofalnych zmian
w budowie strony. Dotyczy to zwłaszcza wstawiania lub usuwania elementów z początku,
a zwłaszcza z samego końca strony (często znika lub zostaje niepoprawnie umieszczone
odwołanie do pliku Footer.txt).
3
Obsługa baz danych z użyciem ADO.NET
W celu podglądu tabeli klienci w przeglądarce wykonaj następujące czynności:
18. Otwórz plik Default.aspx z podkatalogu bank.
19. Kliknij w zakładkę Data znajdującą się pod okienkiem projektu po prawej stronie
ekranu.
20. Upewnij się, czy masz otwarte połączenie do odpowiedniej bazy danych.
21. Znajdź węzeł opisujący tabelę klienci.
22. Przeciągnij tabelę klienci z okienka Data na stronę Default.aspx, przed napis treść
(jest to bezpieczne rozwiązanie). Pojawią się dwie kontrolki: niewizualna — bez
reprezentacji w kodzie HTML — AccessDataSourceControl oraz MxDataGrid. Teraz
dopiero usuń napis treść. Możesz również sprawdzić na zakładce HTML, czy wszystko
jest w porządku.
23. Zapisz dokonane zmiany i przejdź do okna przeglądarki (o ile masz już uruchomioną
aplikację). Wybierz z menu w kategorii Obsługa polecenie Administracja.
24. Sprawdź działanie strony. Zauważ, że domyślnie można klikać w nagłówki kolumn,
żeby zmieniać sposób sortowania danych.
25. Zauważ, że zmieniając w środowisku Web Matrix właściwości kontrolki MxDataGrid,
takie jak PageSize, AllowPaging, AllowSorting, GridLines i inne, jesteś w stanie
wpływać na sposób wyświetlania tabeli na stronie.
26. Zauważ, że widoczne są wszystkie kolumny tabeli (co czasem nie jest pożądane),
oraz że nie zawsze mają one poprawne polskie nazwy (np. id zamiast nr, imie zamiast
imię, komorkowy zamiast tel. komórkowy itp.). Ten problem zostanie rozwiązany przy
samodzielnej obsłudze standardowej kontrolki DataGrid ASP.NET. Można również
ustawić właściwość AutoGenerateFields kontrolki MxDataGrid na False i wskazać,
jakie kolumny mają być widoczne, zmieniając jej kolekcję Fields.
Odłączanie się od bazy danych
27. Kliknij w zakładkę Data znajdującą się pod okienkiem projektu po prawej stronie
ekranu.
28. W widoku drzewa w oknie Data kliknij w nadrzędny węzeł bazy bank.mdb.
29. Kliknij w przycisk Close Database Connection znajdujący się na pasku narzędzi Data.
Uwaga: Dopóki nie zostanie zaznaczony nadrzędny węzeł serwera w widoku drzewa
w oknie Data, przycisk Close Database Connection pozostaje nieaktywny.
Konfiguracja źródła danych
Kontrolka AccessDataSourceControl posiada tylko trzy właściwości. Dwiema
najważniejszymi są ConnectionString oraz SelectCommand. Pierwsza określa źródło
danych, w tym wykorzystywany sterownik oraz pełną ścieżkę do pliku bazy .mdb. Druga
4
Obsługa baz danych z użyciem ADO.NET
określa polecenie SQL służące do odczytu danych. Wstawienie takiej kontrolki na stronę
powoduje podstawowy kłopot konfiguracyjny: ścieżka do pliku bazy danych jest za
każdym razem wpisana bezpośrednio w kontrolkę.
O ile czasem konieczne jest to, aby pewne mechanizmy środowiska Web Matrix działały,
stanowi to kłopot przy praktycznym wdrażaniu aplikacji. Zmiana położenia pliku bazy
danych powoduje bowiem konieczność zmiany w kodzie źródłowym stron .aspx. Często
stosowanym i zalecanym rozwiązaniem jest uniezależnienie gotowej aplikacji od
położenia bazy danych, którą wykorzystuje. W ten sposób administrator jest w stanie
zmienić konfigurację aplikacji bez zmiany jej kodu źródłowego. Na szczęście okazuje się,
że twórcy ASP.NET pomyśleli także i o tym. Istnieje bowiem możliwość umieszczenia
własnych informacji konfiguracyjnych w pliku konfiguracyjnym aplikacji web.config.
Przeniesiesz teraz informacje o sposobie łączenia się z bazą danych z pliku
bank/Default.aspx do pliku web.config. W tym celu wykonaj poniższe czynności:
30. Otwórz plik Default.aspx z podkatalogu bank projektu (jeśli masz ten plik otwarty, to
przejdź do niego).
31. Kliknij w kontrolkę AccessDataSourceControl i zaznacz cały napis będący wartością
jej właściwości ConnectionString. Zaznaczony napis wytnij do schowka.
32. Otwórz plik web.config z katalogu głównego projektu. Był on tworzony na końcu
modułu 4. Jeśli jeszcze nie masz tego pliku, to stwórz nowy plik konfiguracyjny
aplikacji poleceniem File  New File, wskazując Web.Config w sekcji General. Zapisz
go w katalogu głównym projektu pod wymaganą nazwą web.config.
33. Znajdź umieszczoną w komentarzu nieaktywną sekcję <appSettings>. Zamień
w kluczu "connectionstring" wartość atrybutu value na napis umieszczony
w schowku (czyli poprzednią wartość właściwości ConnectionString kontrolki).
Następnie przenieś koniec komentarza przed samą sekcję <appSettings>, podobnie
jak w poniższym przykładzie:
Przykład 11. Dodanie klucza konfiguracyjnego, opisującego sposób łączenia się z bazą danych
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<!-The <appSettings> section is used to configure
5
Obsługa baz danych z użyciem ADO.NET
application-specific configuration settings.
These can be fetched from within apps by calling the
"ConfigurationSettings.AppSettings(key)" method:
-->
<appSettings>
<add key="connectionstring"
value="Provider=Microsoft.Jet.OLEDB.4.0;
Ole DB Services=-4;
Data Source=C:\ASP.NET\MojBank\dane\bank.mdb"/>
</appSettings>
<system.web>
...
34. Zapisz zmiany dokonane w pliku web.config.
35. Wróć do pliku Default.aspx i stwórz dla strony (Page) obsługę zdarzenia Load. Wpisz
kod ustawiający łańcuch połączenia z bazą danych przy ładowaniu strony:
Przykład 12. Ustawianie właściwości ConnectionString przy ładowaniu strony
void Page_Load(object sender, EventArgs e) {
AccessDataSourceControl1.ConnectionString =
ConfigurationSettings.AppSettings["connectionstring"];
}
36. Zapisz dokonane zmiany i sprawdź, czy wybranie z menu w kategorii Obsługa
polecenia Administracja nadal wyświetla tabelę klientów.
Konfiguracja taka, tzn. zapisana w pliku web.config w postaci pary klucz–wartość, będzie
wykorzystywana już do końca kursu. Pozwala to na łatwe przeniesienie pliku bazy danych
do innego katalogu i aktualizację informacji o tym w jednym miejscu (znów mamy
zastosowanie reguły DRY).
Powyższa zmiana konfiguracji źródła danych (kontrolki AccessDataCourceControl)
powoduje jednak, że pewne opcje środowiska Web Matrix stają się niedostępne — jak
np. lista kolumn tabeli podczas edycji strony w trybie wizualnym. Warto zapamiętać więc,
żeby takie zmiany — jako część konfiguracyjna aplikacji — wprowadzać dopiero po
6
Obsługa baz danych z użyciem ADO.NET
sprawdzeniu poprawności działania strony. W przeciwnym przypadku może okazać się
konieczne przywrócenie niektórym źródłom danych informacji o bazie danych, z których
mają korzystać.
7
Obsługa baz danych z użyciem ADO.NET
5. Kontrolki powiązane z danymi
Podgląd jednej tabeli, jakkolwiek potrzebny, to nie wszystko, co można osiągnąć
korzystając z ADO.NET. Kontrolki ASP.NET mogą być wiązane z danymi pobieranymi
z wybranego źródła danych. Wystarczy więc powiązać kontrolkę z wybraną źródłem
danych (ustawiając właściwość DataSource) oraz wskazać kolumnę (właściwości
DataTextField i/lub DataValueField), aby zobaczyć dane tam się znajdujące. Kontrolki,
które mogą przechować więcej niż jedną wartość mają te właściwości. Z kontrolek
standardowych są to np. DropDownList, RadioButtonList, ListBox, DataGrid. Wymóg
przechowywania wielu wartości ma swoją przyczynę — polecenie SQL SELECT może
przecież zwrócić całą listę wyników.
Dla dowolnej właściwości pozostałych kontrolek można poza tym ustawić powiązania
z danymi, modyfikując kolekcję (DataBindings). W ten sposób wartość dowolnej
właściwości kontrolki może być pobierana ze źródła danych. Sztuką jest tylko zbudowanie
odpowiedniego wyrażenia wiążącego.
Po ustaleniu, co z czym ma być związane, wystarczy zażądać powiązania kontrolek
z danymi — zawsze, gdy trzeba pokazać zmiany w danych. Powiązanie dla każdej
potrzebnej kontrolki odbywa się przez wywołanie jej metody DataBind(). Wiązanie
kontrolek najczęściej odbywa się wewnątrz obsługi zdarzenia Load strony (dla
wyświetlenia wartości początkowych) lub w metodach obsługi innych zdarzeń (gdy po
zmianie danych trzeba zaktualizować interfejs użytkownika).
Warto zauważyć, że jeśli kontrolka jest zawsze wiązana w obsłudze zdarzenia Load
strony, bez sprawdzania warunkiem if (!IsPostBack), czy jest to pierwsze żądanie
strony, to wszelkie zmiany dokonane przez użytkownika w takiej kontrolce są gubione.
Czasem jest to pożądane, ale czasem nie. Istnieje też możliwość wywołania metody
DataBind() dla samej strony — wtedy wywołania metod DataBind() dla pozostałych
kontrolek na niej zawartych wykonywane są automatycznie. Mogą jednak być przy tym
zgubione zmiany w powiązanych kontrolkach (np. wybrana pozycja z listy).
Rozbudujesz teraz stronę Obsługa klienta tak, żeby można było przeglądać informacje
o wybranym kliencie banku. W tym celu wykonaj poniższe czynności:
8
Obsługa baz danych z użyciem ADO.NET
1. Otwórz plik Kasa.aspx z podkatalogu bank.
2. Wstaw na stronę z okienka Toolbox, z zakładki Web Controls kontrolkę
AccessDataSourceControl — przed napisem treść. Zmień nazwę tej kontrolki (jej
właściwość (ID)) na Select_id_klienci.
3. Zamień napis treść na Numer klienta: oraz wstaw za nim kontrolkę listy rozwijanej
DropDownList. Zmień nazwę tej kontrolki (właściwość (ID)) na DdLstId.
4. Wstaw za listą rozwijaną przycisk i zmień jego nazwę (ID) na BtnOdswiez.
5. Ustaw właściwości kontrolek zgodnie z poniższą tabelą:
Typ kontrolki
AccessDataSourceControl
DropDownList
Button
Nazwa właściwości
(ID)
SelectCommand
(ID)
DataSource
DataTextField
DataValueField
AutoPostBack
(ID)
Text
Wartość właściwości
Select_id_klienci
SELECT id FROM [klienci]
DdLstId
Select_id_klienci
id
id
True
BtnOdswiez
Odśwież
6. Dodaj dla strony (Page) obsługę zdarzenia Load. Wpisz pomocniczą metodę
ustawiającą dla źródła danych właściwość ConnectionString na odczytaną z pliku
web.config oraz kod korzystający z tej metody:
Przykład 13. Konfiguracja źródła danych i wiązanie kontrolek z danymi przy pierwszym ładowaniu
strony
void BindControlsToData() {
Select_id_klienci.ConnectionString =
ConfigurationSettings.AppSettings["connectionstring"];
DdLstId.DataBind();
}
void Page_Load(object sender, EventArgs e) {
if (!IsPostBack)
{
BindControlsToData();
}
}
7. Włącz stronę Obsługa klienta i sprawdź, czy po połączeniu się z bazą danych w liście
rozwijanej pojawiły się identyfikatory wierszy z tabeli klienci.
9
Obsługa baz danych z użyciem ADO.NET
8. Dodaj dla przycisku Odśwież obsługę zdarzenia Click. Wpisz kod powodujący
odświeżenie zawartości listy rozwijanej z numerami klientów:
Przykład 14. Ponowne wiązanie kontrolki z danymi
void BtnOdswiez_Click(object sender, EventArgs e) {
BindControlsToData();
}
9. Sprawdź działanie przycisku Odśwież przez dodanie w środowisku Web Matrix nowego
wiersza w tabeli klienci, a następnie wciśnięcie tego przycisku w oknie przeglądarki.
Lista powinna zawierać numer nowo dodanego klienta.
5.1. Korzystanie z modułów generacji kodu
Wyświetlanie numerów klientów to podstawowy element potwierdzający skuteczność
działania. Teraz dodasz kontrolki wyświetlające informacje o kliencie oraz obsługę
zdarzeń. Skorzystasz tu z modułu generacji kodu SELECT Data Code Wizard. Stworzy on
kod z obsługą komponentów ADO.NET, dzięki któremu będzie można pobierać dane
z bazy. W tym celu wykonaj poniższe czynności:
10. Otwórz zakładkę Data w oknie projektu i połącz się z utworzoną wcześniej bazą
bank.mdb.
11. Przełącz się na zakładkę Design i wstaw napisy oraz kontrolki TextBox jak poniżej:
Rysunek 5. Wygląd strony do odczytu podstawowych informacji o klientach
10
Obsługa baz danych z użyciem ADO.NET
12. Ustaw właściwości kontrolek zgodnie z poniższą tabelą:
Typ kontrolki
TextBox
TextBox
Nazwa właściwości
(ID)
ReadOnly
(ID)
ReadOnly
Wartość właściwości
TxtImie
True
TxtNazwisko
True
13. Przełącz się na zakładkę Code i zauważ, jak zmieniła się zawartość okienka Toolbox.
Jest tam wyświetlona zakładka Code Wizards z pięcioma kreatorami — modułami
generowania kodu.
14. Przeciągnij generator kodu SELECT Data Method do okna Code, poniżej metody
BtnOdswiez_Click. Na ekranie pojawi się okno dialogowe Select a Database
Connection.
15. W polu wyboru Select a database wybierz połączenie z bazą danych bank.mdb (jeśli
jest otwarta) lub wskaż pozycję <New Database Connection> i wciśnij przycisk
Create..., aby stworzyć nowe połączenie do tej bazy.
16. Kliknij w przycisk Next.
17. Na ekranie pojawi się okno dialogowe Construct a SELECT query, prezentujące
pierwszy ekran kreatora generacji kodu.
18. Z listy Tables wybierz element klienci.
19. Zaznacz pole wyboru znajdujące się obok pozycji imie oraz nazwisko na liście
Columns. W ten sposób dokonasz wyboru kolumn odczytywanych z tabeli.
20. Kliknij w przycisk WHERE.
21. Na ekranie pojawi się okno dialogowe WHERE Clause Builder.
22. Z listy Column wybierz element id.
Uwaga: Opcja ta określa argumenty znajdujące się na lewo od klauzuli WHERE.
23. Kliknij w przycisk radiowy Filter, a w polu filtru wpisz @id (są to wartości domyślne).
Uwaga: Opcja ta określa argumenty znajdujące się na prawo od klauzuli WHERE.
Wartość ta zostanie przekazana jako parametr przy wykorzystaniu powstałego kodu.
24. Kliknij w przycisk OK.
25. Powrócisz teraz do kreatora SELECT Data Code Wizard i etapu Construct a SELECT
Query. Zauważ, jak zmieniła się zawartość pól WHERE clause oraz Preview.
26. Kliknij w przycisk Next.
27. Na ekranie pojawi się drugie okno dialogowe kreatora SELECT Data Code Wizard,
Query Preview.
28. Kliknij w przycisk Test Query.
29. W polu [klienci].[id] = wpisz 1.
30. Kliknij w przycisk OK.
11
Obsługa baz danych z użyciem ADO.NET
31. Na ekranie zobaczysz okno dialogowe Query Preview, w którym zostanie wyświetlony
wiersz tabeli klienci, odpowiadający warunkowi id = 1.
32. Kliknij w przycisk Next.
33. Na ekranie pojawi się trzecie okno dialogowe kreatora SELECT Data Code Wizard,
Name Method. W polu nazwy metody wpisz DaneKlienta.
34. Kliknij w przycisk radiowy DataSet (jest to wartość domyślna).
35. Kliknij w przycisk Finish.
36. Okno kreatora zniknie, a w widoku Code pojawi się metoda DaneKlienta. Jako
parametr wejściowy przyjmuje ona wartość liczbową id, zaś w wyniku działania
zwraca zestaw danych DataSet. Zwrócony zestaw danych zawiera dane dotyczące
klienta o identyfikatorze id, pobrane z użyciem mechanizmu ADO.NET.
37. Wygenerowany w ten sposób kod ma wpisaną pełną ścieżkę dostępu do pliku
bank.mdb, czyli na pewno będzie poprawnie działać na komputerze, przy którym
pracujesz. Znasz już jednak rozwiązanie tego problemu — wystarczy nieco poprawić
początek metody DaneKlienta, aby ścieżka do bazy była odczytywana z pliku
web.config:
Przykład 15. Odczyt klucza konfiguracyjnego, opisującego sposób łączenia się z bazą danych
System.Data.DataSet DaneKlienta(int id) {
string connectionString =
ConfigurationSettings.AppSettings["connectionstring"];
System.Data.IDbConnection dbConnection = new
System.Data.OleDb.OleDbConnection(connectionString);
string queryString = "SELECT [klienci].[imie], " +
"[klienci].[nazwisko] FROM [klienci] WHERE " +
"([klienci].[id] = @id)";
...
38. Przejdź teraz do zakładki Design i stwórz dla kontrolki DdLstId obsługę zdarzenia
SelectedIndexChanged. Kluczową sprawą jest tutaj ustawiona na True właściwość
AutoPostBack kontrolki. Dzięki temu można reagować na zmianę wybranego numeru
klienta i zgodnie z nim aktualizować zawartość pozostałych kontrolek.
39. Wpisz kod realizujący zmiany w kontrolkach, jak poniżej:
Przykład 16. Odczyt i wyświetlenie informacji o wybranym kliencie
void DdLstId_SelectedIndexChanged(object sender, EventArgs e) {
12
Obsługa baz danych z użyciem ADO.NET
try {
// Odczytanie wartości kolumny id wybranego klienta
string numer = DdLstId.SelectedItem.Value;
int id = Convert.ToInt32(numer);
// Odczytanie wiersza danych z bazy
System.Data.DataSet ds = DaneKlienta(id);
// Wyświetlenie informacji o kliencie
TxtImie.Text = ds.Tables[0].Rows[0]["imie"].ToString();
TxtNazwisko.Text = ds.Tables[0].Rows[0]["nazwisko"].ToString();
}
catch (Exception ex) {
// Zabezpieczenie przed błędem, gdy brak id w bazie
TxtImie.Text = TxtNazwisko.Text = "";
}
}
40. Po zapisaniu zmian i uruchomieniu strony zauważ, że przy pierwszym wejściu na tę
stronę wypełniana jest lista numerów klientów, ale brakuje danych pierwszego
zaznaczonego klienta. Dodaj więc w pomocniczej metodzie BindControlsToData,
wywoływanej przy pierwszym ładowaniu oraz odświeżaniu strony, żądanie aktualizacji
jej zawartości:
Przykład 17. Aktualizacja informacji o kliencie przy pierwszym ładowaniu strony
void BindControlsToData() {
Select_id_klienci.ConnectionString =
ConfigurationSettings.AppSettings["connectionstring"];
DdLstId.DataBind();
// Wymuszona aktualizacja zawartości kontrolek
DdLstId_SelectedIndexChanged(this, null);
}
41. Wróć do przeglądarki i w menu nawigacyjnym wskaż inną stronę, a następnie znów
stronę Obsługa klienta. Sprawdź, czy dane pojawiają się po pierwszym wejściu na
stronę.
5.2. Inne sposoby odczytu danych
13
Obsługa baz danych z użyciem ADO.NET
Jak już było wspomniane, uzyskany w powyższy sposób zbiór danych DataSet jest
najbardziej elastycznym sposobem obsługi danych. Natomiast obiekt DataReader ma
prostszą budowę i pozwala na jednokrotny odczyt uzyskanych danych — tylko w przód.
Dodasz teraz możliwość wyświetlenia adresu klienta przez obiekt DataReader,
a następnie zobaczysz, jak powiązać z danymi kontrolki wyświetlające adres e-mail oraz
numery telefonów klienta, przez wyrażenia wiążące. W tym celu wykonaj poniższe
czynności:
42. Wstaw na stronę przycisk Button Szczegóły >> za nazwiskiem klienta.
43. Poniżej wstaw kontrolkę Panel i umieść na niej kontrolki jak na rysunku:
Rysunek 6. Strona z możliwością wyświetlania szczegółów dotyczących klienta
14
Obsługa baz danych z użyciem ADO.NET
44. Ustaw właściwości kontrolek zgodnie z poniższą tabelą:
Typ kontrolki
Panel
<TABLE>
TextBox
TextBox
TextBox
TextBox
TextBox
TextBox
HyperLink
Nazwa właściwości
(ID)
Width
border
height
width
(ID)
ReadOnly
(ID)
ReadOnly
(ID)
ReadOnly
(ID)
ReadOnly
(ID)
ReadOnly
(ID)
ReadOnly
(ID)
Text
Wartość właściwości
PanelSzczegoly
580px
1
140px
570px
TxtAdres
True
TxtKod
True
TxtMiasto
True
TxtKraj
True
TxtDomowy
True
TxtKomorkowy
True
LnkEmail
(brak)
45. Przełącz się na zakładkę Code i przeciągnij ponownie generator kodu SELECT Data
Method do okna Code, poniżej metody DdLstId_SelectedIndexChanged. Na ekranie
pojawi się okno dialogowe Select a Database Connection.
46. Aktywne jest ostatnie, właściwe połączenie. Kliknij w przycisk Next.
47. W liście kolumn zaznacz: adres, kod, miasto i kraj.
48. Kliknij w przycisk WHERE.
49. Kliknij w przycisk OK.
50. Kliknij w przycisk Next.
51. Jeśli chcesz, możesz sprawdzić budowę zapytania klikając w przycisk Test Query.
52. Kliknij w przycisk Next.
53. W polu nazwy metody wpisz AdresKlienta.
54. Kliknij tym razem (to ważne!) w przycisk radiowy DataReader.
55. Kliknij w przycisk Finish.
56. Okno kreatora zniknie, a w widoku Code pojawi się metoda AdresKlienta. Jako
parametr wejściowy przyjmuje ona wartość liczbową id, lecz w wyniku działania
zwraca obiekt DataReader.
57. Wygenerowany w ten sposób kod ma wpisaną pełną ścieżkę dostępu do pliku
bank.mdb. Popraw początek metody AdresKlienta, aby ścieżka do bazy była
odczytywana z pliku web.config:
Przykład 18. Odczyt z bazy danych adresu wybranego klienta
15
Obsługa baz danych z użyciem ADO.NET
System.Data.IDataReader AdresKlienta(int id) {
string connectionString =
ConfigurationSettings.AppSettings["connectionstring"];
System.Data.IDbConnection dbConnection = new
System.Data.OleDb.OleDbConnection(connectionString);
string queryString = "SELECT [klienci].[adres], " +
"[klienci].[kod], [klienci].[miasto], [klienci].[kraj] " +
"FROM [klienci] WHERE ([klienci].[id] = @id)";
...
58. Powyższa metoda zwraca obiekt posiadający interfejs o nazwie IDataReader. Jednak,
żeby móc odczytać z uzyskanego obiektu dane, trzeba będzie odzyskać jego właściwy
typ, wykonując rzutowanie do konkretnej klasy. Z analizy treści metody
AdresKlienta wynika, że w tym przypadku będzie to
System.Data.OleDb.OleDbDataReader. Już za chwilę wykorzystasz ten fakt.
59. Dodaj w metodzie Page_Load ustawienie początkowego stanu panelu jako
niewidoczny:
Przykład 19. Ukrycie panelu ze szczegółami przy pierwszym ładowaniu strony
void Page_Load(object sender, EventArgs e) {
if (!IsPostBack)
{
PanelSzczegoly.Visible = false;
BindControlsToData();
}
}
60. Przejdź teraz do zakładki Design i stwórz dla przycisku BtnSzczegoly obsługę
zdarzenia Click. Wpisz kod poniższych metod, które przełączają widoczność panelu
ze szczegółami klienta oraz aktualizują zawarte w nim kontrolki:
Przykład 20. Odczyt z bazy adresu wybranego klienta
void BtnSzczegoly_Click(object sender, EventArgs e) {
PanelSzczegoly.Visible = !PanelSzczegoly.Visible;
if (PanelSzczegoly.Visible)
{
16
Obsługa baz danych z użyciem ADO.NET
BtnSzczegoly.Text = "<< Ukryj";
try {
// Wywołanie z odczytanym numerem klienta
PokazAdresKlienta(Convert.ToInt32(DdLstId.SelectedItem.Value));
}
catch (Exception ex) {
// Na wypadek błędu - usunięcie danych
PokazAdresKlienta(0);
}
}
else
{
BtnSzczegoly.Text = "Szczegóły >>";
}
}
void PokazAdresKlienta(int id) {
try {
// Odczytanie adresu z bazy danych, odzyskanie typu obiektu
System.Data.OleDb.OleDbDataReader dr =
(System.Data.OleDb.OleDbDataReader) AdresKlienta(id);
// Sprawdzenie, czy ostrzymaliśmy dane
if (dr.HasRows && dr.Read()) {
// Wyświetlenie adresu klienta
TxtAdres.Text
= dr["adres"].ToString();
TxtKod.Text
= dr["kod"].ToString();
TxtMiasto.Text = dr["miasto"].ToString();
TxtKraj.Text
= dr["kraj"].ToString();
}
else {
// Żądanie usunięcia danych
id = 0;
}
}
catch (Exception ex) {
// Żądanie usunięcia danych
id = 0;
}
if (id == 0) {
// Usunięcie danych
17
Obsługa baz danych z użyciem ADO.NET
TxtAdres.Text = TxtKod.Text = TxtMiasto.Text = TxtKraj.Text = "";
}
}
61. Takie rozwiązanie działa świetnie dla aktualnego klienta. Jeśli natomiast numer
klienta zostanie zmieniony, w czasie gdy otwarte są szczegóły, dane te pozostają bez
zmian. Dlatego trzeba jeszcze rozbudować metodę obsługi zdarzenia
SelectedIndexChanged:
Przykład 21. Wyświetlanie szczegółów klienta przy zmianach numeru klienta
void DdLstId_SelectedIndexChanged(object sender, EventArgs e) {
try {
// Odczytanie wartości kolumny id wybranego klienta
string numer = DdLstId.SelectedItem.Value;
int id = Convert.ToInt32(numer);
// Odczytanie wiersza danych z bazy
System.Data.DataSet ds = DaneKlienta(id);
// Wyświetlenie informacji o kliencie
TxtImie.Text = ds.Tables[0].Rows[0]["imie"].ToString();
TxtNazwisko.Text = ds.Tables[0].Rows[0]["nazwisko"].ToString();
if (PanelSzczegoly.Visible)
{
// Wyświetlenie adresu klienta
PokazAdresKlienta(id);
}
}
catch (Exception ex) {
// Zabezpieczenie przed błędem, gdy brak id w bazie
TxtImie.Text = "";
TxtNazwisko.Text = "";
}
}
5.3. Wiązanie kontrolek z danymi
Trzecim sposobem wyświetlania danych jest użycie wiązania kontrolek z danymi. Na
początku modułu podany był przykład, gdzie wartość właściwości kontrolki była określona
jako wartość wskazanej właściwości innej kontrolki. W przypadku odczytu danych z bazy
18
Obsługa baz danych z użyciem ADO.NET
sytuacja jest trochę inna — aby skorzystać z wiązania danych muszą istnieć globalnie
dostępne symbole, które będą użyte przy budowie wyrażeń wiążących. Następnie przed
wywołaniem metod DataBind() trzeba spowodować, żeby wspomniane symbole
zawierały dane przeznaczone do wyświetlenia.
Zrobisz teraz ostatnie zmiany na stronie Kasa.aspx, tak aby były wyświetlane opcjonalne
szczegóły dotyczące klienta: numery telefonów i adres e-mail. Wykorzystany zostanie do
tego mechanizm wiązania kontrolek z danymi. W tym celu wykonaj poniższe czynności:
1. Przełącz się na zakładkę Code i przeciągnij generator kodu SELECT Data Method do
okna Code, poniżej metody PokazAdresKlienta. Na ekranie pojawi się okno
dialogowe Select a Database Connection.
2. Aktywne jest ostatnie, właściwe połączenie. Kliknij w przycisk Next.
3. W liście kolumn zaznacz: domowy, komorkowy i email.
4. Kliknij w przycisk WHERE.
5. Kliknij w przycisk OK.
6. Kliknij w przycisk Next.
7. Jeśli chcesz, możesz sprawdzić budowę zapytania klikając w przycisk Test Query.
8. Kliknij w przycisk Next.
9. W polu nazwy metody wpisz SzczegolyKlienta.
10. Kliknij (to ważne!) w przycisk radiowy DataReader.
11. Kliknij w przycisk Finish.
12. Okno kreatora zniknie, a w widoku Code pojawi się metoda SzczegolyKlienta. Jako
parametr wejściowy przyjmuje ona wartość liczbową id, zaś w wyniku działania
zwraca obiekt DataReader.
13. Wygenerowany w ten sposób kod ma wpisaną pełną ścieżkę dostępu do pliku
bank.mdb. Popraw początek metody SzczegolyKlienta, aby ścieżka do bazy była
odczytywana z pliku web.config:
Przykład 22. Odczyt z bazy danych szczegółów wybranego klienta
System.Data.IDataReader SzczegolyKlienta(int id) {
string connectionString =
ConfigurationSettings.AppSettings["connectionstring"];
System.Data.IDbConnection dbConnection = new
19
Obsługa baz danych z użyciem ADO.NET
System.Data.OleDb.OleDbConnection(connectionString);
string queryString = "SELECT [klienci].[domowy], " +
"[klienci].[komorkowy], [klienci].[email] " +
"FROM [klienci] WHERE ([klienci].[id] = @id)";
...
14. Wpisz za wygenerowaną metodą SzczegolyKlienta deklarację globalnej zmiennej
SzczegolyDataReader, jak poniżej:
Przykład 23. Deklaracja globalnej zmiennej wykorzystywanej przy wiązaniu danych
System.Data.OleDb.OleDbDataReader SzczegolyDataReader;
15. Przejdź na zakładkę Design i zaznacz kontrolkę TxtDomowy. Znajdź na samej górze
okienka z listą właściwości kolekcję powiązań z danymi (DataBindigs). Otwórz okienko
TxtDomowy Bindings, klikając w przycisk z wielokropkiem.
16. Na liście Bindable Properties wskaż właściwość Text (jest domyślnie zaznaczona).
Kliknij w przycisk radiowy Custom binding expression i wpisz w okienku poniżej
następujące wyrażenie wiążące:
SzczegolyDataReader["domowy"]
17. Kliknij w przycisk OK.
18. Zaznacz kontrolkę TxtKomorkowy. Znajdź kolekcję powiązań z danymi (DataBindigs).
Otwórz okienko TxtKomorkowy Bindings, klikając w przycisk z wielokropkiem.
19. Na liście Bindable Properties wskaż właściwość Text (jest domyślnie zaznaczona).
Kliknij w przycisk radiowy Custom binding expression i wpisz w okienku poniżej
następujące wyrażenie wiążące:
SzczegolyDataReader["komorkowy"]
20. Kliknij w przycisk OK.
21. Zaznacz kontrolkę LnkEmail. Znajdź kolekcję powiązań z danymi (DataBindigs).
Otwórz okienko LnkEmail Bindings, klikając w przycisk z wielokropkiem.
22. Na liście Bindable Properties wskaż właściwość Text (jest domyślnie zaznaczona).
Kliknij w przycisk radiowy Custom binding expression i wpisz w okienku poniżej
następujące wyrażenie wiążące:
(SzczegolyDataReader["email"].ToString() == "") ? "(brak)" :
SzczegolyDataReader["email"]
23. Wyrażenie to wyświetla adres e-mail, o ile jest podany. W przeciwnym przypadku
wyświetla napis „(brak)”.
24. Na liście Bindable Properties wskaż teraz właściwość NavigateUrl. Kliknij w przycisk
radiowy Custom binding expression i wpisz w okienku poniżej następujące wyrażenie
20
Obsługa baz danych z użyciem ADO.NET
wiążące:
(SzczegolyDataReader["email"].ToString() == "") ? "" : "mailto:" +
SzczegolyDataReader["email"]
25. Wyrażenie to konstruuje wartość atrybutu href dla odnośnika (znacznika <a>),
w postaci gotowego do kliknięcia łącza. Składają się na nie napis mailto: oraz adres
e-mail, o ile jest podany. W przeciwnym przypadku adres docelowy łącza będzie
pusty.
26. Pozostaje jeszcze w odpowiednim momencie zażądać powiązania kontrolek z danymi.
Dodaj więc dla strony (Page) obsługę zdarzenia PreRender. Jest to moment,
w którym wszystko na stronie jest już zrobione, ale generowanie kodu HTML dla
kontrolek jeszcze się nie rozpoczęło. Wpisz w treści metody poniższy kod:
Przykład 24. Odczyt z bazy danych szczegółów wybranego klienta
void Page_PreRender(object sender, EventArgs e) {
if (PanelSzczegoly.Visible)
{
int id;
try {
id = Convert.ToInt32(DdLstId.SelectedItem.Value);
}
catch (Exception ex) {
// Zabezpieczenie przed brakiem danych w kontrolce DdLstId
id = 0;
}
// Odczytanie szczegółów wybranego klienta
SzczegolyDataReader =
(System.Data.OleDb.OleDbDataReader) SzczegolyKlienta(id);
// Wiązanie kontrolek z danymi
if (SzczegolyDataReader.HasRows)
{
SzczegolyDataReader.Read();
TxtDomowy.DataBind();
TxtKomorkowy.DataBind();
LnkEmail.DataBind();
}
}
}
21
Obsługa baz danych z użyciem ADO.NET
27. Zapisz dokonane zmiany i sprawdź działanie strony.
Podsumowując należy zauważyć, że do wyświetlania szczegółów klienta na powyższej
stronie zostały użyte aż trzy mechanizmy: odczyt danych przez DataSet (imię
i nazwisko), odczyt danych przez DataReader (adres) oraz wiązanie kontrolek z danymi
(telefony i e-mail). Mimo to, wszystkie szczegóły klienta można było wyświetlić jedną
z tych trzech metod. Wykorzystanie wszystkich mechanizmów naraz miało tylko na celu
prezentację ich możliwości.
22
Obsługa baz danych z użyciem ADO.NET
6. Złożone operacje na danych
Użycie i konfiguracja kontrolki DataGrid
Pierwszym sposobem szybkiego wyświetlenia danych na stronie było użycie kontrolki
MxDataGrid. Zobaczysz teraz, jakie możliwości daje w praktyce tradycyjna siatka
danych, czyli kontrolka ASP.NET DataGrid. Stworzysz teraz stronę z taką kontrolką,
dzięki czemu będzie można nie tylko przeglądać dane, ale także je zmieniać
— z możliwością zatwierdzenia lub porzucenia zmian.
Rysunek 7. Strona zawierająca siatkę danych, z możliwością edycji
W tym celu wykonaj poniższe czynności:
1.
Rozpocznij od otworzenia strony Default.aspx z katalogu bank.
2.
Pod umieszczoną tam kontrolką MxDataGrid wstaw odnośnik do strony, na której
będzie można dokonywać przeglądu i edycji tych samych danych. Odnośnik wstaw
poleceniem HTML  Insert HyperLink, zaś w wyświetlonym oknie wpisz
następujące dane: Edycja danych (dla Description) oraz DaneKlientow.aspx (dla
URL). Możesz zamknąć plik Default.aspx.
3.
Otwórz plik Strona.aspx z podkatalogu temp i zapisz kopię tego pliku w
podkatalogu bank projektu, pod nazwą DaneKlientow.aspx.
23
Obsługa baz danych z użyciem ADO.NET
Przejdź na zakładkę HTML i popraw ścieżki do plików włączanych:
4.
<!-- #Include file="Header.txt" -->
na:
<!-- #Include file="../Header.txt" -->
oraz:
<!-- #Include file="Footer.txt" -->
na:
<!-- #Include file="../Footer.txt" -->
5.
Wróć do zakładki Design i zmień tytuł strony na Dane klientów.
6.
Wstaw na stronę przed napisem treść kontrolkę AccessDataSourceControl i
nazwij ją (właściwość (ID)) Select_klienci.
7.
Usuń napis treść i wstaw kontrolkę DataGrid. Nazwij ją GridKlienci.
8.
Wstaw w następnym akapicie odnośnik do poprzedniej strony, na której można
tylko przeglądać dane klientów. Odnośnik wstaw poleceniem HTML  Insert
HyperLink, zaś w wyświetlonym oknie wpisz następujące dane: Zakończenie
edycji (dla Description) oraz Default.aspx (dla URL).
Stwórz dla strony (Page) obsługę zdarzenia Load. Wpisz kod ustawiający łańcuch
9.
połączenia z bazą danych oraz wiążący siatkę z danymi przy ładowaniu strony:
Przykład 25. Ustawianie właściwości ConnectionString i wiązanie danych przy pierwszym
ładowaniu strony
void Page_Load(object sender, EventArgs e) {
if (!IsPostBack) {
Select_klienci.ConnectionString =
ConfigurationSettings.AppSettings["connectionstring"];
GridKlienci.DataBind();
}
}
10.
Otwórz plik konfiguracyjny aplikacji web.config i skopiuj łańcuch połączenia do
bazy danych bank.mdb (wartość atrybutu value klucza connectionstring – tekst
pomiędzy cudzysłowami). Możesz po tym zamknąć plik web.config.
11.
Przełącz się na zakładkę Design i wklej skopiowany łańcuch połączenia do
właściwości ConnectionString kontrolki Select_klienci.
Mimo że jest to wbrew stosowanej w tym module praktyce, istnieją dwie przyczyny
uzasadniające takie rozwiązanie. Po pierwsze — dzięki temu Web Matrix pozwoli lepiej
skonfigurować kontrolkę GridKlienci. Po drugie — nadpisywanie w zdarzeniu
Page_Load właściwości ConnectionString wartością odczytaną z pliku
24
Obsługa baz danych z użyciem ADO.NET
konfiguracyjnego zabezpiecza przed problemami wynikającymi z pozostawienia
ścieżki do bazy danych w kodzie strony. Dobrą praktyką będzie natomiast usunięcie
tej ścieżki po skończeniu pracy nad stroną.
12.
Ustaw pozostałe właściwości kontrolek zgodnie z poniższą tabelą. Zauważ moment
połączenia z bazą danych oraz to, jak zmienia się zawartość siatki danych
GridKlienci po zmianie jej właściwości DataSource:
Typ kontrolki
AccessDataSourceControl
DataGrid
Nazwa właściwości
(ID)
ConnectionString
SelectCommand
(ID)
AutoGenerateColumns
DataSource
Wartość właściwości
Select_klienci
odczytany z pliku web.config
SELECT * FROM [klienci]
GridKlienci
False
Select_klienci
13.
Pod okienkiem właściwości znajdź link Property Builder i kliknij w niego.
14.
Na zakładce General w liście rozwijanej Data key field wskaż element id.
15.
Na zakładce Columns rozwiń węzeł drzewa nazwany Button Column. Kliknij w
element Edit, Update, Cancel, a następnie w przycisk > . Do siatki danych zostanie
dodana pierwsza kolumna, pozwalająca na wykonywanie operacji edycji oraz
zatwierdzanie bądź anulowanie wprowadzonych zmian.
16.
Ustaw napisy wyświetlane podczas pracy:
 Edit Text na: Edycja,
 UpdateText na: Zapisz,
 Cancel Text na: Anuluj.
17.
Wskaż w liście Available columns pod węzłem Data Fields element All Fields i
— wciskając przycisk > — dodaj wszystkie kolumny.
18.
Ustaw napisy wyświetlane w nagłówkach kolumn, klikając kolejno w nazwy
kolumn
w prawej liście Selected Columns. Zmień właściwość Header text dla kolumn
odpowiednio na: id  Nr, imie  Imię, nazwisko  Nazwisko, adres  Ulica,
kod  Kod, miasto  Miasto, kraj  Kraj, domowy  Tel. domowy, komorkowy 
Tel. komórkowy, email  e-mail.
19.
Na zakładce Format wskaż w liście Objects pozycję DataGrid i ustaw jej
właściwość Back color na wybrany kolor (sugestia: Bisque).
20.
Podobnie wskaż w liście Objects pozycję Header i ustaw jej właściwość Back color
na inny wybrany kolor (sugestia: SandyBrown).
21.
Wciśnij przycisk Apply u dołu okna, aby zobaczyć wprowadzone zmiany. Jeśli
wolisz inne kolory, możesz je dowolnie zmieniać.
25
Obsługa baz danych z użyciem ADO.NET
22.
Na zakładce Borders z listy rozwijanej Grid Lines wybierz wartość Both (wartość
domyślna) oraz ustaw właściwość Border Color na wybrany kolor (sugestia: Gray).
23.
Zatwierdź zmiany przyciskiem OK.
24.
Zapisz stronę i uruchom ją. Kontrolka DataGrid powinna wyświetlić dane z tabeli
klienci, ale edycja danych jeszcze nie będzie możliwa. Niebawem się to zmieni.
Edycja i anulowanie edycji
25.
W celu umożliwienia przejścia do edycji danych w kontrolce DataGrid, w obsłudze
zdarzenia rozpoczęcia edycji należy programowo ustawić jej właściwość
EditItemIndex. Przejdź następnie do zakładki Design i zaznacz kontrolkę
GridKlienci.
26.
Dodaj dla kontrolki GridKlienci obsługę zdarzenia EditCommand. Wpisz poniższy
kod:
Przykład 26. Przejście do edycji wiersza w siatce danych DataGri
void GridKlienci_EditCommand(object sender, DataGridCommandEventArgs e) {
GridKlienci.EditItemIndex = e.Item.ItemIndex;
GridKlienci.DataBind();
}
27.
Wróć do zakładki Design i dodaj dla kontrolki GridKlienci także obsługę
zdarzenia CancelCommand. Wpisz poniższy kod:
Przykład 27. Przejście do edycji wiersza w siatce danych DataGrid
void GridKlienci_CancelCommand(object sender, DataGridCommandEventArgs e) {
GridKlienci.EditItemIndex = -1;
GridKlienci.DataBind();
}
28. Zapisz i uruchom stronę. Powinno dać się edytować dane i anulować edycję.
Zapisywanie danych
Teraz dodasz jeszcze możliwość zapisywania zmian. Najpierw jednak musisz utworzyć
kod, który będzie zapisywał zmiany do bazy danych.
29. Przełącz się na zakładkę Code i z zakładki Code Wizards znajdującej się w oknie
Toolbox przeciągnij generator kodu UPDATE Data Method poniżej metody
GridKlienci_CancelCommand.
26
Obsługa baz danych z użyciem ADO.NET
30. Na ekranie pojawi się okno dialogowe Select a Database Connection. W polu Select
a database wybierz połączenie z bazą danych bank.mdb (jeśli jest otwarta) lub wskaż
pozycję <New Database Connection> i wciśnij przycisk Create..., aby stworzyć nowe
połączenie do tej bazy.
31. Kliknij w przycisk Next.
32. Na ekranie pojawi się okno dialogowe Construct an UPDATE query, prezentujące
pierwszy ekran kreatora generacji kodu.
33. W liście kolumn zaznacz: imie, nazwisko, adres, kod, miasto, kraj, domowy,
komorkowy oraz email. Za każdym razem musisz podać nazwę parametru, który
będzie użyty w wyrażeniu SQL. Domyślne wartości są całkowicie wystarczające.
34. Kliknij w przycisk WHERE.
35. Kliknij w przycisk OK.
36. Kliknij w przycisk Next.
37. Jeśli chcesz, możesz sprawdzić budowę zapytania klikając przycisk Test Query.
38. Kliknij w przycisk Next.
39. W polu nazwy metody wpisz ZapiszDaneKlienta.
40. Kliknij w przycisk Finish.
41. Wygenerowany w ten sposób kod ma wpisaną pełną ścieżkę dostępu do pliku
bank.mdb. Popraw początek metody ZapiszDaneKlienta, aby ścieżka do bazy była
odczytywana z pliku web.config. Popraw również treść zapytania queryString:
Przykład 28. Zapisanie zmienionych danych wskazanego klienta
int ZapiszDaneKlienta(int id, string imie, string nazwisko,
string adres, string kod, string miasto, string kraj,
string domowy, string komorkowy, string email)
{
string connectionString =
ConfigurationSettings.AppSettings["connectionstring"];
System.Data.IDbConnection dbConnection =
new System.Data.OleDb.OleDbConnection(connectionString);
string queryString = "UPDATE [klienci] SET [imie]=@imie, " +
"[nazwisko]=@nazwisko, [adres]=@adres, [kod]=@kod, " +
"[miasto]=@miasto, [kraj]=@kraj, [domowy]=@domowy, " +
"[komorkowy]=@komorkowy, [email]=@email " +
"WHERE ([klienci].[id] = @id)";
...
27
Obsługa baz danych z użyciem ADO.NET
42. W pewnych przypadkach występuje mimo wszystko problem — tak skonstruowane
zapytanie nie zapisuje modyfikacji w bazie. W takim wypadku przenieś dodatkowo
definicję parametru @id na koniec listy parametrów:
Przykład 29. Przeniesienie parametru @id na koniec listy parametrów
...
dbCommand.CommandText = queryString;
dbCommand.Connection = dbConnection;
System.Data.IDataParameter dbParam_id =
new System.Data.OleDb.OleDbParameter();
dbParam_id.ParameterName = "@id";
dbParam_id.Value = id;
dbParam_id.DbType = System.Data.DbType.Int32;
dbCommand.Parameters.Add(dbParam_id);
System.Data.IDataParameter dbParam_imie =
new System.Data.OleDb.OleDbParameter();
...
dbParam_email.DbType = System.Data.DbType.String;
dbCommand.Parameters.Add(dbParam_email);
System.Data.IDataParameter dbParam_id =
new System.Data.OleDb.OleDbParameter();
dbParam_id.ParameterName = "@id";
dbParam_id.Value = id;
dbParam_id.DbType = System.Data.DbType.Int32;
dbCommand.Parameters.Add(dbParam_id);
int rowsAffected = 0;
dbConnection.Open();
...
43. Wróć do zakładki Design i dodaj dla kontrolki GridKlienci obsługę zdarzenia
UpdateCommand. Wpisz poniższy kod:
Przykład 30. Kod testujący przysyłane parametry w obsłudze zdarzenia UpdateCommand
void GridKlienci_UpdateCommand(object sender, DataGridCommandEventArgs e) {
// Wyświetlenie przysłanych parametrów. UKRYĆ W KOMENTARZU!
string s = "";
for (int i = 0; i < Request.Form.Count; i++)
28
Obsługa baz danych z użyciem ADO.NET
s += "[" + i + "]=" + Request.Form[i] + "<br>";
Status.Text = s;
Status.Visible = true;
// Zakończenie edycji
GridKlienci.EditItemIndex = -1;
GridKlienci.DataBind();
}
44. Po zakończeniu edycji i naciśnięciu łącza Zapisz do strony wysyłane są parametry
formularza edycyjnego. Są one umieszczane w tablicy Request.Form.
45. W powyższym kodzie zaznaczona jest sekcja wyświetlająca w etykiecie Status
indeksy w tablicy Request.Form oraz wartości przysłanych w ten sposób parametrów.
Jest to kod testujący, który należy usunąć lub ukryć w komentarzu po zakończeniu
pracy nad stroną.
46. Zapisz zmiany, wywołaj edycję wiersza z siatki danych i naciśnij łącze Zapisz.
47. Zauważ, że pod indeksem [3] przysyłany jest numer klienta, zaś pod indeksami od
[4] do [12] pozostałe parametry.
48. Pojawia się jednak mały problem. Kolumna id z numerem klienta jest niestety
dostępna do edycji. Można więc wpisać tam inną liczbę i spowodować, że zostanie
wysłane żądanie zmiany danych innego klienta. Aby sobie z tym poradzić, trzeba
znaleźć rozwiązanie, które w trybie edycji pozwala jedynie zobaczyć numer klienta
(nie pozwalając na jego zmianę), ale aby równocześnie numer nadal był wysyłany
z pozostałymi danymi.
49. Przełącz się więc ponownie na zakładkę Design i zaznacz kontrolkę GridKlienci.
Znajdź link Property Builder i kliknij w niego.
50. W zakładce Columns, w liście Selected Columns, zaznacz kolumnę Nr. Kliknij w link
znajdujący się na dole okna Convert this column into a Template Column.
51. Naciśnij przycisk OK i przejdź do zakładki HTML.
52. Zauważ, że zamiast dotychczas umieszczonej tam kolumny <asp:BoundColumn>
pojawiła się kolumna <asp:TemplateColumn>. Jest to kolumna, która posiada dwie
sekcje definiujące jej zawartość: <ItemTemplate> dla wyświetlania danych oraz
<EditItemTemplate> dla edycji danych.
53. Zmień definicję kolumny Nr na poniższą:
29
Obsługa baz danych z użyciem ADO.NET
Przykład 31. Zmiana zawartości kolumny Nr dla edycji danych
...
<asp:EditCommandColumn ButtonType="LinkButton" UpdateText="Zapisz"
CancelText="Anuluj" EditText="Edycja"></asp:EditCommandColumn>
<asp:TemplateColumn HeaderText="Nr">
<ItemTemplate>
<asp:Label runat="server"
Text='<%# DataBinder.Eval(Container, "DataItem.id") %>'>
</asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:Label runat="server"
Text='<%# DataBinder.Eval(Container, "DataItem.id") %>'>
</asp:Label>
<input type="hidden" name="klient_id"
value='<%# DataBinder.Eval(Container, "DataItem.id") %>'>
</EditItemTemplate>
</asp:TemplateColumn>
<asp:BoundColumn DataField="imie" HeaderText="Imię"></asp:BoundColumn>
...
54. Wprowadzona modyfikacja polega na zamianie w sekcji <EditItemTemplate>
kontrolki TextBox na Label oraz na dodaniu dodatkowego pola ukrytego, o nazwie
klient_id i zawartości takiej samej jak poprzedzająca go etykietka. W efekcie
dostępne jest już tylko wyświetlanie danych zamiast ich edycji.
55. Zapisz zmiany i sprawdź, czy osiągnięty został założony cel — po wejściu do edycji
i naciśnięciu linku Zapisz nadal są przysyłane takie same parametry, ale nie można
zmieniać numeru klienta.
56. Zmień definicję metody GridKlienci_UpdateCommand jak poniżej:
Przykład 32. Zapisanie danych po zakończeniu edycji
void GridKlienci_UpdateCommand(object sender, DataGridCommandEventArgs e) {
/**********************************************************
// Wyświetlenie przysłanych parametrów. UKRYĆ W KOMENTARZU!
string s = "";
for (int i = 0; i < Request.Form.Count; i++)
s += "[" + i + "]=" + Request.Form[i] + "<br>";
30
Obsługa baz danych z użyciem ADO.NET
Status.Text = s;
Status.Visible = true;
**********************************************************/
// Zapisanie danych
if (Request.Form.Count >= 12) {
ZapiszDaneKlienta(Convert.ToInt32(Request.Form[3]),
Request.Form[4], Request.Form[5], Request.Form[6],
Request.Form[7], Request.Form[8], Request.Form[9],
Request.Form[10], Request.Form[11], Request.Form[12]);
}
// Zakończenie edycji
GridKlienci.EditItemIndex = -1;
GridKlienci.DataBind();
}
31

Podobne dokumenty