Microsoft.NET: Warstwa dostępu do danych (DAL) w aplikacjach ASP.NET Web Forms Do realizacji projektu potrzebne jest zintegrowane środowisko programistyczne Microsoft Visual Studio 2008 oraz serwer bazy danych SQL Server Express 2005 (lub SQL Server Express 2008 pod warunkiem instalacji Service Pack 1 dla Visual Studio 2008). Alternatywnie można wykorzystać zdalny serwer Oracle lub SQL Server z bazą danych zawierającą tabele PRACOWNICY, ZESPOLY, ETATY. Przed przystąpieniem do realizacji ćwiczeń należy sprawdzić w opisany poniżej sposób dostępność lokalnej instalacji SQL Server Express i jej integrację z Visual Studio. 1. Sprawdzenie czy zainstalowany i uruchomiony jest lokalny serwer bazy danych SQL Server Express (i uruchomienie go jeśli jest zainstalowany, a nie uruchomiony) a. Usługi b. SQL Server Configuration Manager (dostępny z menu Start) W przypadku gdy SQL Server Express nie jest zainstalowany lokalnie, należy wykorzystać zdalny serwer SQL Express lub Oracle. Wtedy w ćwiczeniu pierwszym w punkcie 2 b) jako źródło danych należy wybrać Oracle Database, a jako dostawcę danych.net Framework Data Provider for Oracle. Następnie zamiast poleceń z punktu 2 c) należy wprowadzić nazwę serwera, użytkownika i hasło. Pole Save my password powinno być zaznaczone.
2. Sprawdzenie konfiguracji Visual Studio w zakresie współpracy z SQL Server Express (Tools Options). Ćwiczenie 1 Celem ćwiczenia jest przygotowanie prostej aplikacji ASP.NET, w której warstwa prezentacji komunikuje się bezpośrednio z bazą danych. Podejście to sprawdza się jedynie w prostych aplikacjach, gdyż może prowadzić do duplikowania kodu odpowiedzialnego za komunikację z bazą danych i utrudnia jego pielęgnację, a ponadto ściśle uzależnia warstwę prezentacji od schematu bazy danych. Kroki ćwiczenia: 1. Utworzenie nowej witryny (Web Site). a) Uruchom narzędzie Microsoft Visual Studio. b) Z menu głównego wybierz File New Web Site. Wybierz szablon ASP.NET Web Site, język Visual C# i lokalizację File System. Zaakceptuj zaproponowany katalog lub zmień go na inny gdy nie masz prawa zapisu w proponowanym katalogu. Kliknij przycisk OK.
2. Utworzenie połączenia z bazą danych w środowisku MS Visual Studio a) W panelu Server Explorer wywołaj prawym klawiszem myszy menu kontekstowe dla węzła Data Connections i wybierz opcję Add Connection. b) Jako źródło danych wybierz Microsoft SQL Server Database File. Kliknij przycisk Continue.
c) Pobierz na dysk lokalny plik bazy danych Instytut.mdf. Wróć do Visual Studio i korzystając z przycisku Browse... zlokalizuj pobrany na dysk plik bazy danych.
d) Przetestuj połączenie przyciskiem Test Connection i w przypadku powodzenia kliknij przycisk OK. e) W panelu Server Explorer rozwiń węzeł reprezentujący utworzone połączenie, następnie rozwiń węzeł Tables aby upewnić się, że w bazie danych dostępna jest tabela PRACOWNICY. (Możesz podejrzeć zawartość tabeli PRACOWNICY wywołując prawym klawiszem myszy menu kontekstowe i wybierając z niego opcję Show Table Data.) 3. Utworzenie formularza do edycji informacji o pracownikach. a) Zmień nazwę utworzonej wraz z projektem strony Default.aspx na SqlDataSource.aspx wybierając opcję Rename z menu kontekstowego w panelu Solution Explorer (automatycznie powinna zmienić się również nazwa pliku code behind). b) Przejdź do edycji strony SqlDataSource.aspx w trybie Design. c) Przejdź do panelu Server Explorer. Rozwiń gałąź reprezentującą utworzone wcześniej połączenie z bazą danych. Następnie rozwiń dla tego połączenia gałąź Tables.
d) Techniką drag-and-drop umieść tabelę PRACOWNICY na stronie SqlDataSource.aspx. e) W menu podręcznym dla umieszczonej przez kreator kontrolki typu GridView zaznacz opcje Enable Editing i Enable Deleting. f) Zapisz wszystkie zmiany (np. File Save All). g) Uruchom stronę wybierając z menu kontekstowego opcję View in Browser. Strona w przeglądarce powinna zawierać tabelkę z danymi wszystkich pracowników z możliwością ich edycji i usuwania. 4. Otwórz stronę w dwóch przeglądarkach. Sprawdź co stanie się w przypadku współbieżnej modyfikacji tego samego wiersza. W tym celu: a) w pierwszej przeglądarce kliknij Edit dla któregoś wiersza b) w drugiej przeglądarce kliknij Edit dla tego samego wiersza c) w obu przeglądarkach zmodyfikuj płacę podstawową tego samego pracownika, ustawiając dwie różne wartości d) kliknij Update najpierw w jednej a potem w drugiej przeglądarce.
Ćwiczenie 2 Celem ćwiczenia jest modyfikacja strony z poprzedniego ćwiczenia poprzez konfigurację optymistycznego zarządzania współbieżnością. Kroki ćwiczenia: 1. Kliknij znacznik inteligentny kontrolki SqlDataSource i wybierz opcję Configure Data Source... 2. Przejdź do ekranu Configure the Select Statement, kliknij przycisk Advanced i zaznacz pole wyboru Use Optimistic Concurrency. Następnie kliknij OK i Finish. 3. Obejrzyj zmienione wskutek włączenia optymistycznego zarządzania współbieżnością właściwości kontrolki SqlDataSource: ConflictDetection (CompareAllValues zamiast OverwriteChanges) i DeleteQuery/UpdateQuery, wtórych klauzula WHERE została rozszerzona o warunki odwołujące się do oryginalnych wartości. 4. Przetestuj zachowanie strony przy współbieżnych modyfikacjach (sposobem z pkt.4 poprzedniego ćwiczenia). 5. W obecnej postaci aplikacji nie występuje problem ślepego nadpisywania zmian dokonanych przez inną transakcję. Problemem jest jednak to, że modyfikacje drugiej transakcji są ignorowane bez żadnego komunikatu dla użytkownika. Aby wykryć konflikt operacji i poinformować użytkownika o jego wystąpieniu umieścimy na stronie etykietę z komunikatem o błędzie, która będzie widoczna, gdy operacja UPDATE lub DELETE nie znajdzie żadnego pasującego do warunku WHERE wiersza w bazie danych: a) Umieść na stronie komponent etykiety. Zmień jej identyfikator na ErrorLabel. Wprowadź dla niej stosowny tekst i ustaw jej właściwość widzialności na false.
b) W palecie właściwości komponentu GridView przełącz się na zakładkę Events i utwórz procedury obsługi zdarzeń RowDeleted i RowUpdated. c) Wprowadź następującą treść utworzonych metod obsługi zdarzeń: protected void GridView1_RowDeleted(object sender, GridViewDeletedEventArgs e) { if (e.affectedrows == 0) ErrorLabel.Visible = true; else ErrorLabel.Visible = false; } protected void GridView1_RowUpdated(object sender, GridViewUpdatedEventArgs e) { if (e.affectedrows == 0) { ErrorLabel.Visible = true; e.keepineditmode = true; GridView1.DataBind(); } else ErrorLabel.Visible = false; } d) Ponownie przetestuj zachowanie strony przy współbieżnych modyfikacjach. Ćwiczenie 3 Celem ćwiczenia jest przygotowanie prostej aplikacji ASP.NET z wydzieloną warstwą dostępu do danych (Data Access Layer DAL), zaimplementowaną w oparciu o silnie typowane zbiory danych. Kroki ćwiczenia: 1. Utworzenie silnie typowanego zbioru danych i związanego z nim obiektu Table Adapter w ramach tworzonej witryny. a) Z menu głównego wybierz opcję File New File, a następnie szablon DataSet. Jako nazwę pliku podaj Instytut.xsd. Kliknij przycisk Add, a następnie w oknie dialogowym które zostanie wyświetlone zaakceptuj propozycję umieszczenia zbioru danych w folderze App_Code.
b) Z poziomu okna edycji dla utworzonego zbioru danych (DataSet) wywołaj prawym klawiszem menu kontekstowe i wybierz opcję Add TableAdapter c) W pierwszym kroku kreatora TableAdapter wybierz połączenie z bazą danych. Jeśli pojawi się komunikat sugerujący przeniesienie pliku bazy danych (MDF) do folderu projektu, zgódź się. d) W kolejnym oknie kreatora wybierz (pozostaw) opcję dostępu do bazy danych przez polecenia SQL (bez pośrednictwa procedur składowanych).
e) W kolejnym oknie korzystając z pomocniczego kreatora Query Builder zbuduj zapytanie wybierające wszystkie kolumny z tabeli ETATY. f) Kliknij przycisk Advanced Options i upewnij się że z opcji zaawansowanych wybrana jest tylko pierwsza. Następnie kliknij OK.
g) Przejdź do kolejnego kroku kreatora i zaznacz w nim opcje generacji wszystkich metod proponowanych przez kreator: obu możliwych sposobów wypełniania obiektu DataTable wynikami zapytania i metod umożliwiających uaktualnianie wierszy w bazie danych pojedynczo (a nie jedynie przenoszenie zmian dla wszystkich wierszy zbioru danych poprzez jego metodę Update()). Zmień nazwę drugiej metody na GetEtaty. h) Kliknij Next>, a następnie Finish. Zapisz wszystkie zmiany. 2. Utworzenie strony ASP.NET prezentującej odczytane z bazy danych dane o etatach w formie tabelki.
a) Utwórz w ramach bieżącej witryny nową stronę, wybierając z menu opcję File New File, a następnie szablon Web Form. Jako jej nazwę podaj ObjectDataSource.aspx, a jako język Visual C#. b) Przełącz się na edycję strony ObjectDataSource.aspx w trybie Design. c) Umieść na stronie kontrolkę ObjectDataSource d) Poprzez inteligentny znacznik kontrolki ObjectDataSource wybierz opcję Configure Data Source. Następnie jako obiekt biznesowy dla kontrolki wybierz utworzony wcześniej Table Adapter dla tabeli ETATY. (Jeśli nie ma go na liście wyboru, zapisz zmiany i spróbuj ponownie.) e) W następnym kroku kreatora obejrzyj przypisanie metod warstwy DAL do operacji SELECT, INSERT, UPDATE i DELETE. Nie dokonuj żadnych zmian i kliknij Finish. f) Umieść na stronie kontrolkę GridView i jako źródło danych dla niej wybierz dodaną wcześniej kontrolkę ObjectDataSource.
g) W menu podręcznym dla umieszczonej przez kreator kontrolki typu GridView zaznacz opcje Enable Editing i Enable Deleting. h) Zapisz wszystkie zmiany (np. File Save All). i) Uruchom stronę wybierając z menu kontekstowego opcję View in Browser. Ćwiczenie 4 Celem ćwiczenia jest konfiguracja optymistycznego zarządzania współbieżnością dla architektury opartej o kontrolkę ObjectDataSource pośredniczącą w dostępie do warstwy DAL zaimplementowanej w formie obiektów DataSet. Kroki ćwiczenia: 1. Uruchom stronę z poprzedniego ćwiczenia w dwóch przeglądarkach. Przetestuj zachowanie się strony przy współbieżnych modyfikacjach tego samego wiersza. 2. Przejdź do edycji zbioru danych Instytut.xsd. Korzystając z menu kontekstowego dla obiektu TableAdapter wybierz opcję Configure. 3. W okienku konfiguracji TableAdapter dla tabeli ETATY kliknij przycisk Advanced Options i zaznacz optymistyczne zarządzanie współbieżnością. Kliknij Finish.
4. Przejdź do edycji właściwości kontrolki ObjectDataSource na stronie ObjectDataSource.aspx. Zmień wartość właściwości ConflictDetection na CompareAllValues. Jest to konieczne aby kontrolka przekazywała metodom warstwy DAL nie tylko aktualne wartości danych, ale również oryginalne, które są niezbędne do funkcjonowania optymistycznego zarządzania współbieżnością. 5. Poprzez inteligentny znacznik kontrolki GridView wybierz opcję Configure Data Source. Przejdź do drugiego okna kreatora i wybierz nowe metody warstwy DAL dla operacji UPDATE i DELETE. Dla operacji UPDATE wybierz metodę, która nie przewiduje modyfikacji nazwy etatu. 6. Przetestuj zachowanie się strony w kontekście modyfikacji dokonywanych współbieżnie. 7. Zmodyfikuj stronę ObjectDataSource.aspx tak aby w przypadku konfliktu współbieżnych operacji pojawiał się komunikat informujący użytkownika o zaistniałej sytuacji: a) Wykonaj te same kroki co we wcześniejszym ćwiczeniu wykorzystującym kontrolkę SqlDataSource (Zad. 2, pkt 5, kroki a) b) i c)). b) Przetestuj zachowanie się strony w kontekście modyfikacji dokonywanych współbieżnie. c) Kontrolka ObjectDataSource w przeciwieństwie do SqlDataSource nie ustawia automatycznie liczby zmienionych wierszy (domyślnie zawsze ustawia tę właściwość na -1). Należy więc dodać procedury obsługi zdarzeń Updated i Deleted dla kontrolki ObjectDataSource i ustawić w nich właściwość AffectedRows na wartość zwróconą przez warstwę DAL: e.affectedrows = (int)e.returnvalue; d) Ponownie przetestuj zachowanie strony przy współbieżnych modyfikacjach tego samego wiersza.
8. W aktualnej formie aplikacja wymaga jeszcze dopracowania, gdyż nie we wszystkich scenariuszach użytkownik jest właściwie informowany o zaistniałym konflikcie współbieżnych operacji. Jednym z problemów jest np. to, że gdy w przypadku konfliktu między dwoma operacjami UPDATE użytkownik, który zostanie poinformowany o konflikcie zrezygnuje z modyfikacji klikając Cancel, komunikat o błędzie będzie nadal widoczny. a) Przetestuj powyższy scenariusz z anulowaniem chęci modyfikacji po zaistniałym konflikcie. b) Spróbuj samodzielnie zmodyfikować aplikację, tak aby w powyższym scenariuszu komunikat o błędzie znikał ze strony.