Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Autor: Scott Mitchell
W tym samouczku zaczniemy od samego początku i utworzymy warstwę dostępu do danych (DAL) przy użyciu typowych zestawów danych, aby uzyskać dostęp do informacji w bazie danych.
Wprowadzenie
Jako deweloperzy sieci Web nasze życie koncentruje się na pracy z danymi. Tworzymy bazy danych do przechowywania danych, kodu w celu ich pobierania i modyfikowania oraz stron internetowych do zbierania i podsumowywania. Jest to pierwszy samouczek z długiej serii, który będzie eksplorować techniki implementowania tych typowych wzorców w ASP.NET 2.0. Zaczniemy od utworzenia architektury oprogramowania składającej się z warstwy dostępu do danych (DAL) przy użyciu typowych zestawów danych, warstwy logiki biznesowej (BLL), która wymusza niestandardowe reguły biznesowe i warstwę prezentacji składającą się z ASP.NET stron, które współużytkują wspólny układ strony. Po ułożeniu tej podstawy zaplecza przejdziemy do raportowania, pokazując, jak wyświetlać, podsumowywać, zbierać i weryfikować dane z aplikacji internetowej. Te samouczki są zaprojektowane tak, aby były przedstawione w zwięzły sposób i zawierały szczegółowe instrukcje z wieloma zrzutami ekranu, aby krok po kroku wizualnie poprowadzić Cię przez cały proces. Każdy samouczek jest dostępny w wersjach języka C# i Visual Basic oraz zawiera pobieranie kompletnego kodu. (Ten pierwszy samouczek jest dość długi, ale pozostałe są prezentowane w znacznie bardziej przystępnych częściach).
W przypadku tych samouczków będziemy używać bazy danych Northwind w wersji programu Microsoft SQL Server 2005 Express Edition umieszczonej w katalogu App_Data. Oprócz pliku App_Data bazy danych folder zawiera również skrypty SQL do tworzenia bazy danych, jeśli chcesz użyć innej wersji bazy danych. Jeśli używasz innej wersji programu SQL Server bazy danych Northwind, musisz zaktualizować NORTHWNDConnectionString ustawienie w pliku aplikacji Web.config . Aplikacja internetowa została skompilowana przy użyciu programu Visual Studio 2005 Professional Edition jako projektu witryny sieci Web opartej na systemie plików. Jednak wszystkie samouczki będą działać równie dobrze z bezpłatną wersją programu Visual Studio 2005, Visual Web Developer.
W tym samouczku zaczniemy od samego początku i utworzymy warstwę dostępu do danych (DAL), a następnie utworzymy warstwę logiki biznesowej (BLL) w drugim samouczku i będziemy pracować nad układem strony i nawigacją w trzecim. Samouczki po trzecim będą oparte na fundamentach określonych w pierwszych trzech. W tym pierwszym samouczku omówiliśmy wiele kwestii, więc uruchom program Visual Studio i zacznijmy!
Krok 1. Tworzenie projektu internetowego i nawiązywanie połączenia z bazą danych
Przed utworzeniem warstwy dostępu do danych (DAL) należy najpierw utworzyć witrynę internetową i skonfigurować bazę danych. Zacznij od utworzenia nowej witryny internetowej opartej na systemie plików ASP.NET. Aby to zrobić, przejdź do menu Plik i wybierz pozycję Nowa witryna sieci Web, wyświetlając okno dialogowe Nowa witryna sieci Web. Wybierz szablon witryny sieci Web ASP.NET. Ustaw listę rozwijaną Lokalizacja na System plików, wybierz folder, w którym umieścisz witrynę sieci Web, a następnie ustaw język na Visual Basic.
Rysunek 1. Tworzenie nowej witryny sieci Web opartej na systemie plików (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Spowoduje to utworzenie nowej witryny sieci Web ze Default.aspx stroną ASP.NET, folderem App_Data i plikiem Web.config .
Po utworzeniu witryny internetowej następnym krokiem jest dodanie odwołania do bazy danych w Eksploratorze serwera programu Visual Studio. Dodając bazę danych do Eksploratora serwera, można dodawać tabele, procedury składowane, widoki itd. z poziomu programu Visual Studio. Możesz również wyświetlić dane tabeli lub utworzyć własne zapytania ręcznie lub graficznie za pomocą konstruktora zapytań. Ponadto, podczas tworzenia typowanych zestawów danych dla DAL musimy wskazać programowi Visual Studio bazę danych, z której powinny być konstruowane typowane zestawy danych. Chociaż możemy podać te informacje o połączeniu w tym momencie, program Visual Studio automatycznie wypełnia listę rozwijaną baz danych już zarejestrowanych w Eksploratorze serwera.
Kroki w celu dodania bazy danych Northwind do Eksploratora serwera zależą od tego, czy chcesz użyć bazy danych SQL Server 2005 Express Edition znajdującej się w folderze App_Data, czy też masz skonfigurowany serwer z bazą danych Microsoft SQL Server 2000 lub 2005, którego chcesz użyć zamiast tego.
Używanie bazy danych w folderzeApp_Data
Jeśli nie masz serwera bazy danych programu SQL Server 2000 lub 2005 do nawiązania połączenia lub po prostu chcesz uniknąć konieczności dodawania bazy danych do serwera bazy danych, możesz użyć wersji programu SQL Server 2005 Express Edition bazy danych Northwind znajdującej się w folderze pobranej witryny internetowej App_Data (NORTHWND.MDF).
Baza danych umieszczona w folderze App_Data jest automatycznie dodawana do Eksploratora serwera. Zakładając, że na maszynie jest zainstalowany program SQL Server 2005 Express Edition, powinien zostać wyświetlony węzeł o nazwie NORTHWND.MDF w Eksploratorze serwera, który można rozwinąć, aby eksplorować jego tabele, widoki, procedury składowane itd. (zobacz Rysunek 2).
Folder App_Data może również przechowywać pliki programu Microsoft Access .mdb , które, podobnie jak ich odpowiedniki programu SQL Server, są automatycznie dodawane do Eksploratora serwera. Jeśli nie chcesz używać żadnej z opcji programu SQL Server, zawsze możesz zainstalować bazę danych Northwind Traders i aplikacje oraz umieścić je w katalogu App_Data. Należy jednak pamiętać, że bazy danych programu Access nie są tak bogate w funkcje jak program SQL Server i nie są przeznaczone do użycia w scenariuszach witryny sieci Web. Ponadto kilka z ponad 35 samouczków wykorzysta niektóre funkcje na poziomie bazy danych, które nie są obsługiwane przez Access.
Nawiązywanie połączenia z bazą danych na serwerze bazy danych programu Microsoft SQL Server 2000 lub 2005
Alternatywnie możesz nawiązać połączenie z bazą danych Northwind zainstalowaną na serwerze bazy danych. Jeśli serwer bazy danych nie ma jeszcze zainstalowanej bazy danych Northwind, należy najpierw dodać ją do serwera bazy danych, uruchamiając skrypt instalacyjny uwzględniony w pobieraniu tego samouczka.
Po zainstalowaniu bazy danych przejdź do Eksploratora serwera w programie Visual Studio, kliknij prawym przyciskiem myszy węzeł Połączenia danych i wybierz polecenie Dodaj połączenie. Jeśli nie widzisz Eksploratora serwera, przejdź do widoku/Eksploratora serwera lub naciśnij Ctrl+Alt+S. Spowoduje to wyświetlenie okna dialogowego Dodawanie połączenia, w którym można określić serwer do nawiązania połączenia, informacje o uwierzytelnieniu i nazwę bazy danych. Po pomyślnym skonfigurowaniu informacji o połączeniu z bazą danych i kliknięciu przycisku OK baza danych zostanie dodana jako węzeł pod węzłem Połączenia danych. Możesz rozwinąć węzeł bazy danych, aby przeglądać jego tabele, widoki, procedury składowane itd.
Rysunek 2: Dodaj połączenie z bazą danych Northwind serwera bazy danych
Krok 2. Tworzenie warstwy dostępu do danych
Podczas pracy z danymi jedną z opcji jest osadzanie logiki specyficznej dla danych bezpośrednio w warstwie prezentacji (w aplikacji internetowej strony ASP.NET tworzą warstwę prezentacji). Może to przybrać formę pisania kodu ADO.NET w sekcji kodu strony ASP.NET lub używając kontrolki SqlDataSource w sekcji znaczników. W obu przypadkach takie podejście ściśle łączy logikę dostępu do danych z warstwą prezentacji. Zalecane jest jednak oddzielenie logiki dostępu do danych od warstwy prezentacji. Ta oddzielna warstwa jest nazywana warstwą dostępu do danych, w skrócie DAL, i jest zwykle implementowana jako oddzielny projekt biblioteki klas. Zalety tej architektury warstwowej są dobrze udokumentowane (zobacz sekcję "Dalsze informacje" na końcu tego samouczka, aby uzyskać informacje na temat tych zalet) i jest podejściem, które weźmiemy w tej serii.
Cały kod specyficzny dla danego źródła danych, takie jak tworzenie połączenia z bazą danych, wydawanie poleceń SELECT, INSERT, UPDATE i DELETE, i tak dalej, powinien znajdować się w warstwie dostępu do danych (DAL). Warstwa prezentacji nie powinna zawierać żadnych odwołań do takiego kodu dostępu do danych, ale zamiast tego powinna wykonywać połączenia do DAL dla wszystkich żądań danych. Warstwy dostępu do danych zwykle zawierają metody uzyskiwania dostępu do bazowych danych bazy danych. Na przykład baza danych Northwind zawiera tabele Products i Categories, które rejestrują produkty na sprzedaż oraz kategorie, do których należą. W naszej warstwie dostępu do danych (DAL) będą takie metody, jak:
-
GetCategories(),które będą zwracać informacje o wszystkich kategoriach -
GetProducts(), które będą zwracać informacje o wszystkich produktach -
GetProductsByCategoryID(categoryID), które zwróci wszystkie produkty należące do określonej kategorii -
GetProductByProductID(productID), które będą zwracać informacje o konkretnym produkcie
Te metody, po wywołaniu, będą łączyć się z bazą danych, wystawiać odpowiednie zapytanie i zwracać wyniki. Sposób zwracania tych wyników jest ważny. Te metody mogłyby po prostu zwrócić obiekt DataSet lub DataReader wypełniony przez zapytanie bazy danych, ale najlepiej zwracać te wyniki przy użyciu silnie typizowanych obiektów. Obiekt silnie typizowany jest obiektem, którego schemat jest sztywno zdefiniowany w czasie kompilacji, natomiast jego przeciwieństwo, czyli obiekt luźno typizowany, to taki, którego schemat nie jest znany do momentu wykonania.
Na przykład obiekty DataReader i DataSet (domyślnie) są luźno typizowane, ponieważ ich schemat jest definiowany przez kolumny zwracane przez zapytanie bazy danych używane do ich wypełnienia. Aby uzyskać dostęp do określonej kolumny z luźno typizowanej tabeli DataTable, musimy użyć składni, takiej jak : DataTable.Rows(index)("columnName"). Słabe typowanie tabeli DataTable w tym przykładzie jest pokazane przez to, że musimy uzyskać dostęp do nazwy kolumny za pomocą indeksu porządkowego lub ciągu znaków. Z drugiej strony silnie typizowana tabela DataTable będzie mieć każdą z jej kolumn zaimplementowaną jako właściwość, co spowoduje utworzenie kodu, który wygląda następująco: DataTable.Rows(index).columnName.
Aby zwrócić silnie typizowane obiekty, deweloperzy mogą tworzyć własne niestandardowe obiekty biznesowe lub używać Typed DataSets. Obiekt biznesowy jest implementowany przez dewelopera jako klasę, której właściwości zwykle odzwierciedlają kolumny tabeli baz danych, którą reprezentuje obiekt biznesowy. Typed DataSet to klasa wygenerowana przez program Visual Studio na podstawie schematu bazy danych i których składowe są silnie typizowane zgodnie z tym schematem. Sam Typizowany Zestaw Danych składa się z klas, które rozszerzają klasy ADO.NET DataSet, DataTable i DataRow. Oprócz silnie typizowanych tabel DataTable, typizowane zbiory danych (Typed DataSets) zawierają również adaptery tabel (TableAdapters), które są klasami służącymi do wypełniania tabel danych (DataTables) i propagowania modyfikacji w tych tabelach z powrotem do bazy danych.
Uwaga
Aby uzyskać więcej informacji na temat zalet i wad używania typowych zestawów danych w porównaniu z niestandardowymi obiektami biznesowymi, zobacz Projektowanie składników warstwy danych i przekazywanie danych za pośrednictwem warstw.
Na potrzeby architektury tych samouczków użyjemy silnie typionych zestawów danych. Rysunek 3 przedstawia przepływ pracy między różnymi warstwami aplikacji, która używa typów zestawów danych.
Rysunek 3: Cały kod dostępu do danych jest przypisany do DAL (kliknij, aby wyświetlić obraz w pełnym rozmiarze)
Tworzenie typowego zestawu danych i adaptera tabel
Aby rozpocząć tworzenie naszej WARSTWY DOSTĘPU DO DANYCH (DAL), zacznijmy od dodania typizowanego zestawu danych do naszego projektu. Aby to osiągnąć, kliknij prawym przyciskiem myszy węzeł projektu w Eksplorator rozwiązań i wybierz polecenie Dodaj nowy element. Wybierz opcję Zestaw danych z listy szablonów i nadaj jej Northwind.xsdnazwę .
Rysunek 4: Wybierz Dodaj nowy zestaw danych do projektu (kliknij, aby wyświetlić obraz w pełnym rozmiarze)
Po kliknięciu przycisku Dodaj po wyświetleniu monitu o dodanie zestawu danych do App_Code folderu wybierz pozycję Tak. Zostanie wyświetlony Projektant dla Typowanego Zestawu Danych, a następnie zostanie uruchomiony Kreator konfiguracji TableAdapter, co umożliwi dodanie pierwszego elementu TableAdapter do Typowanego Zestawu Danych.
Typowany DataSet służy jako silnie typowana kolekcja danych; Składa się z silnie typowanych wystąpień DataTable, z których każdy składa się z silnie typowanych wystąpień DataRow. Utworzymy silnie typizowany DataTable dla każdej z bazowych tabel, z którymi musimy pracować w tej serii samouczków. Zacznijmy od utworzenia tabeli DataTable dla tabeli Products.
Należy pamiętać, że silnie typizowane tabele DataTable nie zawierają żadnych informacji na temat uzyskiwania dostępu do danych z podstawowej tabeli bazy danych. Aby pobrać dane w celu wypełnienia tabeli DataTable, użyjemy klasy TableAdapter, która działa jako warstwa dostępu do danych. W przypadku tabeli Products DataTable narzędzie TableAdapter będzie zawierać metody GetProducts(), GetProductByCategoryID(categoryID)i tak dalej, które wywołamy z warstwy prezentacji. Rola tabeli DataTable polega na byciu silnie typizowanymi obiektami, które służą do przekazywania danych między warstwami.
Kreator konfiguracji TableAdapter zaczyna się od prośby o wybranie bazy danych, z którą chcesz pracować. Lista rozwijana zawiera te bazy danych w Eksploratorze serwera. Jeśli baza danych Northwind nie została dodana do Eksploratora serwera, możesz teraz kliknąć przycisk Nowe połączenie, aby to zrobić.
Rysunek 5. Wybieranie bazy danych Northwind z listy rozwijanej (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Po wybraniu bazy danych i kliknięciu przycisku Dalej pojawi się pytanie, czy chcesz zapisać ciąg połączenia w pliku Web.config. Zapisując ciąg połączenia unikniesz jego twardego zakodowania w klasach TableAdapter, co upraszcza sprawy, jeśli informacje o ciągu połączenia zmienią się w przyszłości. Jeśli zdecydujesz się zapisać ciąg połączenia w pliku konfiguracji, zostanie on umieszczony w sekcji <connectionStrings>, którą można opcjonalnie zaszyfrować w celu zwiększenia bezpieczeństwa lub zmodyfikować później za pomocą nowej strony właściwości ASP.NET 2.0 w narzędziu administracyjnym graficznego interfejsu użytkownika usług IIS, co jest bardziej odpowiednie dla administratorów.
Rysunek 6: Zapisz łańcuch połączenia w Web.config (Kliknij, aby wyświetlić obraz w pełnym rozmiarze)
Następnie musimy zdefiniować schemat dla pierwszej silnie typizowanej tabeli DataTable i podać pierwszą metodę, która ma być używana przez klasę TableAdapter podczas wypełniania silnie typizowanego zestawu danych. Te dwa kroki są wykonywane jednocześnie przez utworzenie zapytania zwracającego kolumny z tabeli, które chcemy odzwierciedlić w tabeli DataTable. Na końcu kreatora nadamy nazwę metody temu zapytaniu. Po osiągnięciu tego celu można wywołać tę metodę z warstwy prezentacji. Metoda spowoduje wykonanie zdefiniowanego zapytania i wypełnienie silnie typizowanej tabeli DataTable.
Aby rozpocząć definiowanie zapytania SQL, musimy najpierw wskazać, jak chcemy, aby program TableAdapter wystawił zapytanie. Możemy użyć instrukcji ad hoc SQL, utworzyć nową procedurę składowaną lub użyć istniejącej procedury składowanej. W tych samouczkach użyjemy instrukcji ad hoc SQL.
Rysunek 7. Wykonywanie zapytań dotyczących danych przy użyciu instrukcji SQL ad hoc (kliknij, aby wyświetlić obraz pełnowymiarowy)
W tym momencie możemy ręcznie wpisać zapytanie SQL. Podczas tworzenia pierwszej metody w tabeli TableAdapter zwykle zapytanie zwraca te kolumny, które muszą być wyrażone w odpowiedniej tabeli DataTable. Możemy to zrobić, tworząc zapytanie zwracające wszystkie kolumny i wszystkie wiersze z Products tabeli:
Rysunek 8. Wprowadź zapytanie SQL w polu tekstowym (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Alternatywnie użyj konstruktora zapytań i graficznie skonstruuj zapytanie, jak pokazano na rysunku 9.
Rysunek 9: Tworzenie zapytania graficznie za pomocą Edytora Power Query (kliknij, aby wyświetlić pełnowymiarowy obraz)
Po utworzeniu zapytania, ale przed przejściem na następny ekran kliknij przycisk Opcje zaawansowane. W projektach witryn internetowych opcja "Generuj instrukcje Wstaw, Aktualizuj i Usuń" jest jedyną zaawansowaną opcją wybraną domyślnie; jeśli uruchomisz tego kreatora z biblioteki klas lub projektu systemu Windows, zostanie również wybrana opcja "Używaj optymistycznej współbieżności". Pozostaw opcję "Użyj optymistycznej współbieżności" niezaznaczoną na razie. Przeanalizujemy optymistyczną współbieżność w przyszłych materiałach szkoleniowych.
Rysunek 10. Wybierz opcję Generuj instrukcje Wstaw, Aktualizuj i Usuń (kliknij, aby wyświetlić pełnowymiarowy obraz)
Po zweryfikowaniu opcji zaawansowanych kliknij przycisk Dalej, aby przejść do ekranu końcowego. W tym miejscu zostanie wyświetlony monit o wybranie metod, które należy dodać do tabeli TableAdapter. Istnieją dwa wzorce wypełniania danych:
-
Wypełnij tabelę DataTable przy użyciu tej metody, która przyjmuje tabelę DataTable jako parametr i wypełnia ją na podstawie wyników zapytania. Na przykład klasa ADO.NET DataAdapter implementuje ten wzorzec przy użyciu metody
Fill(). - Zwróć DataTable za pomocą tej metody, która tworzy i wypełnia DataTable, a następnie zwraca go jako wartość zwracaną metody.
Możesz skonfigurować TableAdapter, aby zaimplementował jeden lub oba te wzorce. Możesz również zmienić nazwy metod podanych tutaj. Pozostawmy zaznaczone oba pola wyboru, mimo że będziemy używać tylko tego ostatniego wzorca w tych samouczkach. Zmieńmy również nazwę raczej ogólnej GetData metody na GetProducts.
Jeśli zaznaczone, ostatnie pole wyboru "GenerateDBDirectMethods" tworzy metody Insert(), Update() i Delete() dla elementu TableAdapter. Jeśli ta opcja nie zostanie zaznaczona, wszystkie aktualizacje będą musiały zostać wykonane za pomocą jedynej metody Update() TableAdapter, która przyjmuje zestaw danych typu, tabelę DataTable, pojedynczy wiersz DataRow lub tablicę wierszy DataRows. (Jeśli nie zaznaczono opcji "Generuj instrukcje Wstaw, Aktualizuj i Usuń" z właściwości zaawansowanych na rysunku 9, to ustawienie tego pola wyboru nie będzie miało żadnego wpływu). Pozostawmy to pole wyboru zaznaczone.
Rysunek 11. Zmień nazwę metody z GetData na GetProducts (kliknij, aby wyświetlić obraz pełnowymiarowy)
Zakończ pracę kreatora, klikając przycisk Zakończ. Po zamknięciu kreatora wrócimy do projektanta zestawu danych, który pokazuje właśnie utworzoną tabelę DataTable. Listę kolumn można wyświetlić w tabeli Products DataTable (ProductID, ProductName, itd.), a także metodami ProductsTableAdapter (Fill() i GetProducts()).
Rysunek 12: DataTable Products i ProductsTableAdapter zostały dodane do typowanego DataSetu (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
W tym momencie mamy typizowany zestaw danych z pojedynczą tabelą DataTable (Northwind.Products) i silnie typizowaną klasą DataAdapter (NorthwindTableAdapters.ProductsTableAdapter) posiadającą metodę GetProducts(). Te obiekty mogą służyć do uzyskiwania dostępu do listy wszystkich produktów z kodu, takiego jak:
Dim productsAdapter As New NorthwindTableAdapters.ProductsTableAdapter()
Dim products as Northwind.ProductsDataTable
products = productsAdapter.GetProducts()
For Each productRow As Northwind.ProductsRow In products
Response.Write("Product: " & productRow.ProductName & "<br />")
Next
Ten kod nie wymagał od nas pisania jednego bitu kodu specyficznego dla dostępu do danych. Nie musieliśmy utworzyć wystąpienia żadnych klas ADO.NET, nie musieliśmy odwoływać się do żadnych ciągów połączenia, zapytań SQL ani procedur składowanych. Zamiast tego narzędzie TableAdapter udostępnia kod dostępu do danych niskiego poziomu.
Każdy obiekt używany w tym przykładzie jest również silnie typizowany, co umożliwia programowi Visual Studio zapewnienie funkcji IntelliSense i sprawdzania typów w czasie kompilacji. **
A co najlepsze, wszystkie tabele danych zwracane przez TableAdapter mogą być powiązane z kontrolkami danych sieci Web ASP.NET, takimi jak GridView, DetailsView, DropDownList, CheckBoxList oraz innymi. W poniższym przykładzie pokazano powiązanie tabeli DataTable zwróconej przez metodę GetProducts() do kontrolki GridView w zaledwie trzech liniach kodu w procedurze obsługi zdarzenia Page_Load.
AllProducts.aspx
<%@ Page Language="VB" AutoEventWireup="true" CodeFile="AllProducts.aspx.vb"
Inherits="AllProducts" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>View All Products in a GridView</title>
<link href="Styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
<form id="form1" runat="server">
<div>
<h1>
All Products</h1>
<p>
<asp:GridView ID="GridView1" runat="server"
CssClass="DataWebControlStyle">
<HeaderStyle CssClass="HeaderStyle" />
<AlternatingRowStyle CssClass="AlternatingRowStyle" />
</asp:GridView>
</p>
</div>
</form>
</body>
</html>
AllProducts.aspx.vb
Imports NorthwindTableAdapters
Partial Class AllProducts
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles Me.Load
Dim productsAdapter As New ProductsTableAdapter
GridView1.DataSource = productsAdapter.GetProducts()
GridView1.DataBind()
End Sub
End Class
Rysunek 13. Lista produktów jest wyświetlana w siatce (kliknij, aby wyświetlić obraz pełnowymiarowy)
Mimo że w tym przykładzie napisaliśmy trzy wiersze kodu w funkcji obsługi zdarzeń strony Page_Load ASP.NET, w przyszłych samouczkach zbadamy, jak używać obiektu ObjectDataSource do deklaratywnego pobierania danych z warstwy dostępu do danych (DAL). W przypadku obiektu ObjectDataSource nie będziemy musieli pisać żadnego kodu i uzyskać obsługę stronicowania i sortowania.
Krok 3. Dodawanie metod sparametryzowanych do warstwy dostępu do danych
W tym momencie nasza ProductsTableAdapter klasa ma tylko jedną metodę , GetProducts()która zwraca wszystkie produkty w bazie danych. Chociaż możliwość pracy ze wszystkimi produktami jest zdecydowanie przydatna, czasami chcemy pobrać informacje o konkretnym produkcie lub wszystkich produktach należących do określonej kategorii. Aby dodać takie funkcje do warstwy dostępu do danych, możemy dodać metody sparametryzowane do tabeli TableAdapter.
Dodajmy metodę GetProductsByCategoryID(categoryID) . Aby dodać nową metodę do DAL, wróć do Projektanta zestawu danych, kliknij prawym przyciskiem myszy w sekcji ProductsTableAdapter i wybierz polecenie Dodaj zapytanie.
Rysunek 14. Kliknij prawym przyciskiem myszy kontrolkę TableAdapter i wybierz polecenie Dodaj zapytanie
Najpierw zostanie wyświetlony monit o to, czy chcemy uzyskać dostęp do bazy danych przy użyciu instrukcji AD-hoc SQL, czy nowej lub istniejącej procedury składowanej. Ponownie użyjemy instrukcji ad hoc SQL. Następnie zapytamy, jakiego typu zapytanie SQL chcemy użyć. Ponieważ chcemy zwrócić wszystkie produkty należące do określonej kategorii, chcemy napisać instrukcję zwracającą SELECT wiersze.
Rysunek 15. Wybierz opcję utworzenia instrukcji zwracającej SELECT wiersze (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Następnym krokiem jest zdefiniowanie zapytania SQL używanego do uzyskiwania dostępu do danych. Ponieważ chcemy zwrócić tylko te produkty, które należą do określonej kategorii, używam tego samego SELECT wyrażenia z GetProducts(), ale dodaję następującą WHERE klauzulę: WHERE CategoryID = @CategoryID. Parametr @CategoryID wskazuje kreatorowi TableAdapter, że metoda, którą tworzymy, będzie wymagała parametru wejściowego odpowiedniego typu (czyli liczby całkowitej, która może być pusta/nieokreślona).
Rysunek 16. Wprowadź zapytanie, aby zwracać tylko produkty w określonej kategorii (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
W ostatnim kroku możemy wybrać wzorce dostępu do danych do użycia, a także dostosować nazwy wygenerowanych metod. W przypadku wzorca Wypełnienia zmieńmy jego nazwę na FillByCategoryID, a dla wzorca zwracania wyników w tabeli DataTable (metody GetX) użyjmy wzorca GetProductsByCategoryID.
Rysunek 17. Wybieranie nazw metod TableAdapter (kliknij, aby wyświetlić obraz pełnowymiarowy)
Po ukończeniu pracy kreatora projektant zestawu danych zawiera nowe metody TableAdapter.
Rysunek 18. Zapytania dotyczące produktów można teraz wykonywać według kategorii
Poświęć chwilę, aby dodać metodę GetProductByProductID(productID) przy użyciu tej samej techniki.
Te sparametryzowane zapytania można przetestować bezpośrednio z poziomu projektanta zestawu danych. Kliknij prawym przyciskiem myszy metodę w tabeli TableAdapter i wybierz pozycję Podgląd danych. Następnie wprowadź wartości, które mają być używane dla parametrów, a następnie kliknij pozycję Podgląd.
Rysunek 19. Te produkty należące do kategorii Napojów są wyświetlane (kliknij, aby wyświetlić obraz pełnowymiarowy)
Za pomocą GetProductsByCategoryID(categoryID) metody w naszym dal możemy teraz utworzyć stronę ASP.NET, która wyświetla tylko te produkty w określonej kategorii. W poniższym przykładzie przedstawiono wszystkie produkty, które znajdują się w kategorii Napoje, które mają CategoryID wartość 1.
Napoje.aspx
<%@ Page Language="VB" AutoEventWireup="true" CodeFile="Beverages.aspx.vb"
Inherits="Beverages" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
<link href="Styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
<form id="form1" runat="server">
<div>
<h1>Beverages</h1>
<p>
<asp:GridView ID="GridView1" runat="server"
CssClass="DataWebControlStyle">
<HeaderStyle CssClass="HeaderStyle" />
<AlternatingRowStyle CssClass="AlternatingRowStyle" />
</asp:GridView>
</p>
</div>
</form>
</body>
</html>
Beverages.aspx.vb
Imports NorthwindTableAdapters
Partial Class Beverages
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles Me.Load
Dim productsAdapter As New ProductsTableAdapter
GridView1.DataSource =
productsAdapter.GetProductsByCategoryID(1)
GridView1.DataBind()
End Sub
End Class
Rysunek 20. Wyświetlane są produkty w kategorii Napojów (kliknij, aby wyświetlić obraz pełnowymiarowy)
Krok 4. Wstawianie, aktualizowanie i usuwanie danych
Istnieją dwa wzorce często używane do wstawiania, aktualizowania i usuwania danych. Pierwszy wzorzec, który nazwę wzorcem bezpośredniego dostępu do bazy danych, obejmuje tworzenie metod, które w przypadku wywołania, wydają polecenie INSERT, UPDATE lub DELETE do bazy danych, która działa na pojedynczym rekordzie. Takie metody są zwykle przekazywane w serii wartości skalarnych (liczb całkowitych, ciągów, wartości logicznych, datetimes itd.), które odpowiadają wartościom do wstawiania, aktualizowania lub usuwania. Na przykład przy użyciu tego wzorca dla Products tabeli metoda delete będzie przyjmować parametr liczby całkowitej, wskazującą ProductID rekordu do usunięcia, podczas gdy metoda insert będzie przyjmować ciąg znaków dla ProductName, liczbę dziesiętną dla UnitPrice, liczbę całkowitą dla UnitsOnStock, i tak dalej.
Rysunek 21. Każde żądanie wstawiania, aktualizowania i usuwania jest wysyłane natychmiast do bazy danych (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Innym wzorcem, który nazywam wzorcem aktualizacji wsadowej, jest zaktualizowanie całego zestawu danych, tabeli DataTable lub kolekcji DataRows w jednym wywołaniu metody. Za pomocą tego wzorca deweloper usuwa, wstawia i modyfikuje wartości DataRows w tabeli DataTable, a następnie przekazuje te wartości DataRows lub DataTable do metody aktualizacji. Następnie ta metoda wylicza przekazane wartości DataRows, określa, czy zostały zmodyfikowane, dodane lub usunięte (za pośrednictwem wartości właściwości RowState elementu DataRow) i wystawiają odpowiednie żądanie bazy danych dla każdego rekordu.
Rysunek 22. Wszystkie zmiany są synchronizowane z bazą danych po wywołaniu metody aktualizacji (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Narzędzie TableAdapter domyślnie używa wzorca aktualizacji wsadowej, ale obsługuje również wzorzec bezpośredni bazy danych. Ponieważ wybraliśmy opcję "Generate Insert, Update, and Delete" (Generuj instrukcje Wstaw, Aktualizuj i Usuń) z właściwości zaawansowanych podczas tworzenia obiektu TableAdapter, ProductsTableAdapter zawiera metodę Update(), która implementuje wzorzec aktualizacji wsadowej. W szczególności TableAdapter zawiera metodę Update(), którą można przekazać typizowanemu zbiorowi danych, silnie typizowanej tabeli DataTable lub co najmniej jednemu wierszowi DataRows. Jeśli pole wyboru "GenerateDBDirectMethods" zostało zaznaczone podczas pierwszego tworzenia TableAdapter, wzorzec bezpośredni bazy danych również zostanie zaimplementowany za pomocą metod Insert(), Update() i Delete().
Oba wzorce modyfikacji danych używają właściwości InsertCommand, UpdateCommand i DeleteCommand TableAdaptera do wydawania poleceń INSERT, UPDATE i DELETE do bazy danych. Możesz sprawdzić i zmodyfikować właściwości InsertCommand, UpdateCommand i DeleteCommand, klikając element TableAdapter w Projektancie zestawu danych, a następnie przechodząc do okna Właściwości. (Upewnij się, że wybrano TableAdapter oraz że obiekt ProductsTableAdapter jest wybrany na liście rozwijanej w oknie Właściwości).
Rysunek 23: Adapter TableAdapter zawiera InsertCommand, UpdateCommand i DeleteCommand właściwości (kliknij, aby wyświetlić obraz w pełnym rozmiarze)
Aby sprawdzić lub zmodyfikować dowolne z tych właściwości polecenia bazy danych, kliknij CommandText podwłaściwość, która spowoduje wyświetlenie Konstruktora zapytań.
Rysunek 24: Konfigurowanie instrukcji INSERT, UPDATE i DELETE w konstruktorze zapytań (kliknij, aby wyświetlić pełnowymiarowy obraz)
Poniższy przykład kodu pokazuje, jak za pomocą wzorca aktualizacji wsadowej podwoić cenę wszystkich produktów, które nie zostały wycofane i które mają 25 jednostek w magazynie lub mniej:
Dim productsAdapter As New NorthwindTableAdapters.ProductsTableAdapter()
Dim products As Northwind.ProductsDataTable = productsAdapter.GetProducts()
For Each product As Northwind.ProductsRow In products
If Not product.Discontinued AndAlso product.UnitsInStock <= 25 Then
product.UnitPrice *= 2
End if
Next
productsAdapter.Update(products)
Poniższy kod ilustruje, jak za pomocą wzorca bezpośredniego bazy danych programowo usunąć określony produkt, a następnie zaktualizować go, a następnie dodać nowy:
Dim productsAdapter As New NorthwindTableAdapters.ProductsTableAdapter()
productsAdapter.Delete(3)
productsAdapter.Update( _
"Chai", 1, 1, "10 boxes x 20 bags", 18.0, 39, 15, 10, false, 1)
productsAdapter.Insert( _
"New Product", 1, 1, "12 tins per carton", 14.95, 15, 0, 10, false)
Tworzenie niestandardowych metod wstawiania, aktualizowania i usuwania
Insert(), Update(), i Delete() metody utworzone przez metodę bezpośrednią bazy danych mogą być nieco kłopotliwe, zwłaszcza w przypadku tabel z wieloma kolumnami. Patrząc na poprzedni przykład kodu, bez pomocy funkcji IntelliSense nie jest szczególnie jasne, która kolumna tabeli Products odpowiada każdemu parametrowi wejściowemu dla metod Update() i Insert(). Czasami chcemy zaktualizować tylko jedną lub dwie kolumny albo dostosować metodę Insert(), która może zwrócić wartość pola IDENTITY (auto-increment) nowo wstawionego rekordu.
Aby utworzyć taką metodę niestandardową, wróć do projektanta zestawu danych. Kliknij prawym przyciskiem myszy element TableAdapter i wybierz polecenie Dodaj zapytanie, wracając do kreatora TableAdapter. Na drugim ekranie możemy wskazać typ zapytania do utworzenia. Utwórzmy metodę, która dodaje nowy produkt, a następnie zwraca wartość nowo dodanego rekordu ProductID. W związku z tym wybierz opcję utworzenia INSERT zapytania.
Rysunek 25. Tworzenie metody dodawania nowego wiersza do Products tabeli (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Na następnym ekranie pojawi się element InsertCommandCommandText. Rozszerz to zapytanie, dodając SELECT SCOPE_IDENTITY() na końcu, co spowoduje zwrócenie ostatnio wstawionej wartości identyfikatora do kolumny IDENTITY w tym samym zakresie. (Zapoznaj się z dokumentacją techniczną, aby uzyskać więcej informacji na temat SCOPE_IDENTITY() i dlaczego prawdopodobnie chcesz użyć SCOPE_IDENTITY() zamiast @@IDENTITY). Upewnij się, że kończysz instrukcję INSERT średnikiem przed dodaniem instrukcji SELECT.
Rysunek 26: Rozszerz zapytanie, aby zwrócić SCOPE_IDENTITY() wartość (kliknij, aby wyświetlić obraz w pełnym rozmiarze)
Na koniec nadaj nowej metodzie InsertProductnazwę .
Rysunek 27. Ustaw nową nazwę metody na InsertProduct (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Po powrocie do projektanta zestawu danych zobaczysz, że element ProductsTableAdapter zawiera nową metodę InsertProduct. Jeśli ta nowa metoda nie ma parametru dla każdej kolumny w tabeli Products, istnieje duże prawdopodobieństwo, że zapomniałeś zakończyć instrukcję INSERT średnikiem. Skonfiguruj metodę InsertProduct i upewnij się, że istnieją średniki rozdzielające instrukcje INSERT i SELECT.
Domyślnie metody wstawiania wykonują metody, które nie są zapytaniami, co oznacza, że zwracają liczbę wierszy, które zostały zmienione. Jednak chcemy, aby metoda InsertProduct zwróciła wartość zwróconą przez zapytanie, a nie liczby wierszy, które zostały zmienione. Aby to osiągnąć, dostosuj właściwość ExecuteMode metody InsertProduct do Scalar.
Rysunek 28. Zmień właściwość na ExecuteModeScalar (kliknij, aby wyświetlić obraz pełnowymiarowy)
Poniższy kod przedstawia nową InsertProduct metodę w akcji:
Dim productsAdapter As New NorthwindTableAdapters.ProductsTableAdapter()
Dim new_productID As Integer = Convert.ToInt32(productsAdapter.InsertProduct( _
"New Product", 1, 1, "12 tins per carton", 14.95, 10, 0, 10, false))
productsAdapter.Delete(new_productID)
Krok 5. Kończenie warstwy dostępu do danych
Należy pamiętać, że ProductsTableAdapters klasa zwraca CategoryID wartości i SupplierID z Products tabeli, ale nie zawiera CategoryName kolumny z tabeli ani Categories kolumny z CompanyNameSuppliers tabeli, chociaż prawdopodobnie są to kolumny, które chcemy wyświetlić podczas wyświetlania informacji o produkcie. Możemy rozszerzyć początkową metodę TableAdapter, GetProducts(), tak aby zawierała zarówno wartości kolumn CategoryName, jak i CompanyName, co spowoduje zaktualizowanie silnie typizowanego DataTable w celu uwzględnienia również tych nowych kolumn.
Może to jednak stanowić problem, ponieważ metody metody tableAdapter do wstawiania, aktualizowania i usuwania danych są oparte na tej początkowej metodzie. Na szczęście metody generowane automatycznie do wstawiania, aktualizowania i usuwania nie mają wpływu na podzapytania w klauzuli SELECT . Dbając o to, by dodać nasze zapytania do Categories i Suppliers jako podzapytania, a nie jako JOIN, unikniemy konieczności przerabiania metod modyfikacji danych. Kliknij prawym przyciskiem myszy metodę GetProducts() w elemecie ProductsTableAdapter i wybierz polecenie Konfiguruj. Następnie dostosuj klauzulę SELECT tak, aby wyglądała następująco:
SELECT ProductID, ProductName, SupplierID, CategoryID,
QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued,
(SELECT CategoryName FROM Categories
WHERE Categories.CategoryID = Products.CategoryID) as CategoryName,
(SELECT CompanyName FROM Suppliers
WHERE Suppliers.SupplierID = Products.SupplierID) as SupplierName
FROM Products
Rysunek 29. Aktualizowanie instrukcji SELECT dla GetProducts() metody (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Po zaktualizowaniu GetProducts() metody w celu użycia tego nowego zapytania tabela DataTable będzie zawierać dwie nowe kolumny: CategoryName i SupplierName.
Rysunek 30. Tabela Products danych ma dwie nowe kolumny
Poświęć chwilę na zaktualizowanie SELECT klauzuli w metodzie GetProductsByCategoryID(categoryID).
Jeśli zaktualizujesz składnię GetProducts()SELECT przy użyciu JOIN narzędzia DataSet Designer, nie będzie można automatycznie wygenerować metod wstawiania, aktualizowania i usuwania danych bazy danych przy użyciu wzorca bezpośredniego bazy danych. Zamiast tego musisz ręcznie utworzyć je podobnie jak to zrobiliśmy z metodą InsertProduct wcześniej w tym samouczku. Ponadto, jeśli chcesz użyć wzorca aktualizacji wsadowej, należy ręcznie podać wartości właściwości InsertCommand, UpdateCommand i DeleteCommand.
Dodawanie pozostałych elementów TableAdapters
Dotychczas przyjrzeliśmy się tylko pracy z pojedynczym TableAdapterem dla pojedynczej tabeli w bazie danych. Jednak baza danych Northwind zawiera kilka powiązanych tabel, z którymi będziemy musieli pracować w naszej aplikacji internetowej. Typowy zestaw danych może zawierać wiele powiązanych tabel Danych. W związku z tym, aby ukończyć nasz DAL, musimy dodać DataTables dla pozostałych tabel, których będziemy używać w tych samouczkach. Aby dodać nowy element TableAdapter do typowego zestawu danych, otwórz projektanta zestawu danych, kliknij prawym przyciskiem myszy w Projektancie i wybierz polecenie Dodaj/TableAdapter. Spowoduje to utworzenie nowej tabeli DataTable i tabeliAdapter oraz przejrzenie kreatora, który omówiliśmy wcześniej w tym samouczku.
Poświęć kilka minut na utworzenie następujących TableAdapters i metod przy użyciu poniższych zapytań. Należy pamiętać, że zapytania w ProductsTableAdapter zawierają zapytania podrzędne, które pobierają nazwy kategorii i dostawców każdego produktu. Ponadto, jeśli śledziłeś, dodałeś już metody klasy ProductsTableAdapterGetProducts()GetProductsByCategoryID(categoryID).
ProduktyAdapter stołu
PobierzProdukty:
SELECT ProductID, ProductName, SupplierID, CategoryID, QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, (SELECT CategoryName FROM Categories WHERE Categories.CategoryID = Products.CategoryID) as CategoryName, (SELECT CompanyName FROM Suppliers WHERE Suppliers.SupplierID = Products.SupplierID) as SupplierName FROM ProductsGetProductsByCategoryID:
SELECT ProductID, ProductName, SupplierID, CategoryID, QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, (SELECT CategoryName FROM Categories WHERE Categories.CategoryID = Products.CategoryID) as CategoryName, (SELECT CompanyName FROM Suppliers WHERE Suppliers.SupplierID = Products.SupplierID) as SupplierName FROM Products WHERE CategoryID = @CategoryIDGetProductsBySupplierID:
SELECT ProductID, ProductName, SupplierID, CategoryID, QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, (SELECT CategoryName FROM Categories WHERE Categories.CategoryID = Products.CategoryID) as CategoryName, (SELECT CompanyName FROM Suppliers WHERE Suppliers.SupplierID = Products.SupplierID) as SupplierName FROM Products WHERE SupplierID = @SupplierIDGetProductByProductID:
SELECT ProductID, ProductName, SupplierID, CategoryID, QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, (SELECT CategoryName FROM Categories WHERE Categories.CategoryID = Products.CategoryID) as CategoryName, (SELECT CompanyName FROM Suppliers WHERE Suppliers.SupplierID = Products.SupplierID) as SupplierName FROM Products WHERE ProductID = @ProductID
CategoriesTableAdapter
Pobierz Kategorie:
SELECT CategoryID, CategoryName, Description FROM CategoriesGetCategoryByCategoryID:
SELECT CategoryID, CategoryName, Description FROM Categories WHERE CategoryID = @CategoryID
DostawcaTableAdapter
PobierzDostawców:
SELECT SupplierID, CompanyName, Address, City, Country, Phone FROM SuppliersGetSuppliersByCountry:
SELECT SupplierID, CompanyName, Address, City, Country, Phone FROM Suppliers WHERE Country = @CountryGetSupplierBySupplierID:
SELECT SupplierID, CompanyName, Address, City, Country, Phone FROM Suppliers WHERE SupplierID = @SupplierID
EmployeesTableAdapter
Zdobądź pracowników:
SELECT EmployeeID, LastName, FirstName, Title, HireDate, ReportsTo, Country FROM EmployeesPobierzPracownikówWedługKierownika:
SELECT EmployeeID, LastName, FirstName, Title, HireDate, ReportsTo, Country FROM Employees WHERE ReportsTo = @ManagerIDGetEmployeeByEmployeeID:
SELECT EmployeeID, LastName, FirstName, Title, HireDate, ReportsTo, Country FROM Employees WHERE EmployeeID = @EmployeeID
Rysunek 31. Projektant zestawu danych po dodaniu czterech elementów TableAdapters (kliknij, aby wyświetlić obraz pełnowymiarowy)
Dodawanie Kodu Niestandardowego do Warstwy Dostępu do Danych
TableAdapters i DataTables dodane do typowanego zestawu danych są wyrażane jako plik definicji schematu XML (Northwind.xsd). Można wyświetlić informacje o schemacie, klikając prawym przyciskiem myszy plik Northwind.xsd w Eksploratorze rozwiązań i wybierając opcję Wyświetl kod.
Rysunek 32. Plik definicji schematu XML (XSD) dla elementu Northwinds Typed DataSet (kliknij, aby wyświetlić obraz pełnowymiarowy)
Te informacje o schemacie są tłumaczone na kod C# lub Visual Basic w czasie projektowania podczas kompilowania lub w czasie wykonywania (w razie potrzeby), w którym momencie można przejść przez nie za pomocą debugera. Aby wyświetlić ten automatycznie wygenerowany kod, przejdź do widoku klas i przejdź do szczegółów klas TableAdapter lub Typed DataSet. Jeśli na ekranie nie widzisz widoku klasy, przejdź do menu Widok i wybierz go z tego miejsca lub naciśnij Ctrl+Shift+C. W widoku klasy można wyświetlić właściwości, metody i zdarzenia klas Typed DataSet i TableAdapter. Aby wyświetlić kod dla określonej metody, kliknij dwukrotnie nazwę metody w widoku klasy lub kliknij ją prawym przyciskiem myszy i wybierz polecenie Przejdź do definicji.
Rysunek 33. Sprawdzanie kodu wygenerowanego automatycznie przez wybranie pozycji Przejdź do definicji w widoku klasy
Chociaż kod generowany automatycznie może być doskonałym oszczędzaniem czasu, kod jest często bardzo ogólny i musi być dostosowany do unikatowych potrzeb aplikacji. Ryzyko rozszerzenia automatycznie wygenerowanego kodu polega jednak na tym, że narzędzie, które wygenerowało kod, może zdecydować, że nadszedł czas na "ponowne wygenerowanie" i zastąpienie dostosowań. Dzięki nowej koncepcji klasy częściowej platformy .NET 2.0 można łatwo podzielić klasę na wiele plików. Dzięki temu możemy dodawać własne metody, właściwości i zdarzenia do klas generowanych automatycznie bez konieczności martwienia się o zastępowanie naszych dostosowań przez program Visual Studio.
Aby zademonstrować sposób dostosowywania DAL, dodajmy metodę GetProducts() do klasy SuppliersRow. Klasa SuppliersRow reprezentuje pojedynczy rekord w Suppliers tabeli; każdy dostawca może dostarczyć zero do wielu produktów, więc GetProducts() zwróci te produkty określonego dostawcy. Aby to zrobić, utwórz nowy plik klasy w App_Code folderze o nazwie SuppliersRow.vb i dodaj następujący kod:
Imports NorthwindTableAdapters
Partial Public Class Northwind
Partial Public Class SuppliersRow
Public Function GetProducts() As Northwind.ProductsDataTable
Dim productsAdapter As New ProductsTableAdapter
Return productsAdapter.GetProductsBySupplierID(Me.SupplierID)
End Function
End Class
End Class
Ta klasa częściowa instruuje kompilator, że podczas kompilowania Northwind.SuppliersRow klasy, aby uwzględnić właśnie zdefiniowaną GetProducts() metodę. Jeśli skompilujesz projekt, a następnie wrócisz do widoku klasy, zobaczysz GetProducts() teraz jako metodę Northwind.SuppliersRow.
Rysunek 34. GetProducts() Metoda jest teraz częścią Northwind.SuppliersRow klasy
Metodę GetProducts() można teraz użyć do wyliczenia zestawu produktów dla określonego dostawcy, jak pokazano w poniższym kodzie:
Dim suppliersAdapter As New NorthwindTableAdapters.SuppliersTableAdapter()
Dim suppliers As Northwind.SuppliersDataTable = suppliersAdapter.GetSuppliers()
For Each supplier As Northwind.SuppliersRow In suppliers
Response.Write("Supplier: " & supplier.CompanyName)
Response.Write("<ul>")
Dim products As Northwind.ProductsDataTable = supplier.GetProducts()
For Each product As Northwind.ProductsRow In products
Response.Write("<li>" & product.ProductName & "</li>")
Next
Response.Write("</ul><p> </p>")
Next
Te dane mogą być również wyświetlane w dowolnym z kontrolek danych sieci Web platformy ASP.NET. Poniższa strona używa kontrolki GridView z dwoma polami:
- Pole BoundField, które wyświetla nazwę każdego dostawcy i
- Pole TemplateField zawierające kontrolkę BulletedList, która jest powiązana z wynikami zwracanymi przez metodę
GetProducts()dla każdego dostawcy.
W przyszłych samouczkach dowiemy się, jak wyświetlać raporty typu główny-szczegóły. Na razie ten przykład został zaprojektowany tak, aby zilustrować użycie metody niestandardowej dodanej Northwind.SuppliersRow do klasy.
DostawcyIProdukty.aspx
<%@ Page Language="VB" CodeFile="SuppliersAndProducts.aspx.vb"
AutoEventWireup="true" Inherits="SuppliersAndProducts" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
<link href="Styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
<form id="form1" runat="server">
<div>
<h1>
Suppliers and Their Products</h1>
<p>
<asp:GridView ID="GridView1" runat="server"
AutoGenerateColumns="False"
CssClass="DataWebControlStyle">
<HeaderStyle CssClass="HeaderStyle" />
<AlternatingRowStyle CssClass="AlternatingRowStyle" />
<Columns>
<asp:BoundField DataField="CompanyName"
HeaderText="Supplier" />
<asp:TemplateField HeaderText="Products">
<ItemTemplate>
<asp:BulletedList ID="BulletedList1"
runat="server" DataSource="<%# CType(CType(Container.DataItem, System.Data.DataRowView).Row, Northwind.SuppliersRow).GetProducts() %>"
DataTextField="ProductName">
</asp:BulletedList>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</p>
</div>
</form>
</body>
</html>
SuppliersAndProducts.aspx.vb
Imports NorthwindTableAdapters
Partial Class SuppliersAndProducts
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles Me.Load
Dim suppliersAdapter As New SuppliersTableAdapter
GridView1.DataSource = suppliersAdapter.GetSuppliers()
GridView1.DataBind()
End Sub
End Class
Rysunek 35. Nazwa firmy dostawcy znajduje się w lewej kolumnie, ich produkty po prawej stronie (kliknij, aby wyświetlić obraz pełnowymiarowy)
Podsumowanie
Podczas tworzenia aplikacji internetowej tworzenie DAL powinno być jednym z pierwszych kroków, które wykonasz, zanim zaczniesz tworzyć warstwę prezentacji. W programie Visual Studio utworzenie dal opartego na typowych zestawach danych to zadanie, które można wykonać w ciągu 10–15 minut bez konieczności pisania wiersza kodu. Samouczki będą opierać się na tym DAL. W następnym samouczku zdefiniujemy szereg reguł biznesowych i zobaczymy, jak zaimplementować je w oddzielnej warstwie logiki biznesowej.
Szczęśliwe programowanie!
Dalsze informacje
Aby uzyskać więcej informacji na temat tematów omówionych w tym samouczku, zapoznaj się z następującymi zasobami:
- Tworzenie DAL przy użyciu silnie typowanych TableAdapters i DataTables w programie VS 2005 i ASP.NET 2.0
- Projektowanie składników warstwy danych i przekazywanie danych za pośrednictwem warstw
- Szyfrowanie informacji o konfiguracji w aplikacjach ASP.NET 2.0
- TableAdapter — omówienie
- Praca z typowanym zestawem danych
- Korzystanie z silnie typizowanego dostępu do danych w programie Visual Studio 2005 i ASP.NET 2.0
- Jak rozszerzyć metody TableAdapter
Szkolenie wideo dotyczące tematów zawartych w tym samouczku
- Warstwy dostępu do danych w aplikacjach ASP.NET
- Jak ręcznie powiązać zestaw danych z usługą Datagrid
- Jak pracować z zestawami danych i filtrami z aplikacji ASP
Informacje o autorze
Scott Mitchell, autor siedmiu książek ASP/ASP.NET i założyciel 4GuysFromRolla.com, współpracuje z technologiami internetowymi firmy Microsoft od 1998 roku. Scott pracuje jako niezależny konsultant, trener i pisarz. Jego najnowsza książka to Sams Teach Yourself ASP.NET 2.0 w 24 godzinach. Można go uzyskać pod adresem mitchell@4GuysFromRolla.com.
Specjalne podziękowania
Ta seria samouczków została omówiona przez wielu przydatnych recenzentów. Główni recenzenci tego samouczka to Ron Green, Hilton Giesenow, Dennis Patterson, Liz Shulok, Abel Gomez i Carlos Santos. Chcesz przejrzeć nadchodzące artykuły MSDN? Jeśli tak, napisz do mnie na adres mitchell@4GuysFromRolla.com.