Tworzenie warstwy dostępu do danych (VB)

Autor: Scott Mitchell

Pobierz plik PDF

W tym samouczku zaczniemy od samego początku i utworzymy warstwę dostępu do danych (DAL), używając 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 badać 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 oraz warstwę prezentacji składającą się z ASP.NET stron, które współużytkują wspólny układ strony. Po ustaleniu podstaw zaplecza przejdziemy do raportowania, pokazując sposób wyświetlania, podsumowywania, zbierania i weryfikowania danych z aplikacji internetowej. Te samouczki są przeznaczone do zwięzłości i zapewniają szczegółowe instrukcje z dużą ilością zrzutów ekranu, aby przejść przez proces wizualnie. 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 szyfrowanych fragmentach).

Na potrzeby tych samouczków będziemy używać wersji bazy danych Northwind firmy Microsoft SQL Server 2005 Express Edition umieszczonej App_Data w katalogu. 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 SQL Server wersji bazy danych Northwind, musisz zaktualizować NORTHWNDConnectionString ustawienie w pliku aplikacjiWeb.config. Aplikacja internetowa została utworzona 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ą opierać się na fundamentach ustanowionych w pierwszych trzech. Mamy wiele do omówienia w tym pierwszym samouczku, 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) najpierw musimy utworzyć witrynę internetową i skonfigurować naszą 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, aby umieścić witrynę internetową, a następnie ustaw język na Visual Basic.

Tworzenie nowego pliku System-Based witrynie sieci Web

Rysunek 1. Tworzenie nowego pliku System-Based witrynie sieci Web (kliknij, aby wyświetlić obraz pełnowymiarowy)

Spowoduje to utworzenie nowej witryny sieci Web ze Default.aspx stroną ASP.NET, folderem App_Data i plikiem Web.config .

Po utworzeniu witryny sieci Web 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 kompilowania typów zestawów danych dla dal należy wskazać program Visual Studio do bazy danych, z której powinny zostać skonstruowane typy 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 dodawania bazy danych Northwind do Eksploratora serwera zależą od tego, czy chcesz użyć bazy danych SQL Server 2005 Express Edition w App_Data folderze, czy jeśli masz serwer bazy danych microsoft SQL Server 2000 lub 2005, którego chcesz użyć.

Używanie bazy danych w folderzeApp_Data

Jeśli nie masz serwera bazy danych 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ć SQL Server 2005 Express Edition wersji 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 zainstalowano SQL Server 2005 Express Edition powinien zostać wyświetlony węzeł o nazwie NORTHWND. MDF w Eksploratorze serwera, który można rozwinąć i eksplorować jego tabele, widoki, procedurę składowaną itd. (zobacz Rysunek 2).

Folder App_Data może również przechowywać pliki programu Microsoft Access.mdb, które, podobnie jak ich odpowiedniki SQL Server, są automatycznie dodawane do Eksploratora serwera. Jeśli nie chcesz używać żadnej z opcji SQL Server, zawsze możesz zainstalować bazę danych i aplikacje firmy Northwind Traders i wpuścić je do App_Data katalogu. Należy jednak pamiętać, że bazy danych programu Access nie są tak bogate w funkcje, jak SQL Server i nie są przeznaczone do użycia w scenariuszach witryny sieci Web. Ponadto kilka samouczków z 35+ będzie korzystać z niektórych funkcji na poziomie bazy danych, które nie są obsługiwane przez program Access.

Nawiązywanie połączenia z bazą danych na serwerze bazy danych 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ł Data Connections i wybierz pozycję Dodaj połączenie. Jeśli nie widzisz Eksploratora serwera, przejdź do widoku/Eksploratora serwera lub naciśnij klawisze 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 Data Connections node. Węzeł bazy danych można rozwinąć, aby eksplorować jego tabele, widoki, procedury składowane itd.

Dodawanie połączenia z bazą danych Northwind serwera bazy danych

Rysunek 2. Dodawanie połączenia 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 składają się na warstwę prezentacji). Może to mieć postać pisania kodu ADO.NET w części kodu strony ASP.NET lub przy użyciu kontrolki SqlDataSource z części 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, dal krótko i jest zwykle implementowana jako oddzielny projekt biblioteki klas. Korzyści wynikające z 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 zajmiemy się tą serią.

Cały kod specyficzny dla bazowego źródła danych, taki jak tworzenie połączenia z bazą danych, wystawianie SELECTpoleceń , INSERT, i DELETEUPDATEtak dalej, powinno znajdować się w dal. Warstwa prezentacji nie powinna zawierać żadnych odwołań do takiego kodu dostępu do danych, ale zamiast tego powinna wykonywać wywołania w dal dla wszystkich żądań danych. Warstwy dostępu do danych zwykle zawierają metody uzyskiwania dostępu do bazowych danych bazy danych. Baza danych Northwind zawiera Products na przykład tabele i Categories rejestrujące produkty do sprzedaży oraz kategorie, do których należą. W naszym dal będziemy mieli metody takie jak:

  • GetCategories(), które będą zwracać informacje o wszystkich kategoriach
  • GetProducts(), które będą zwracać informacje o wszystkich produktach
  • GetProductsByCategoryID(categoryID), który zwróci wszystkie produkty należące do określonej kategorii
  • GetProductByProductID(productID), które będą zwracać informacje o określonym 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. Metody te mogą po prostu zwracać element DataSet lub DataReader wypełniony przez zapytanie bazy danych, ale najlepiej zwracać te wyniki przy użyciu silnie typiowanych obiektów. Obiekt silnie typizowane jest obiektem, którego schemat jest sztywno zdefiniowany w czasie kompilacji, natomiast przeciwieństwo, luźno wpisany obiekt, jest obiektem, którego schemat nie jest znany do czasu wykonania.

Na przykład element DataReader i Zestaw danych (domyślnie) są luźno wpisywane obiekty, 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"). Luźne wpisywanie w tabeli DataTable w tym przykładzie jest wyświetlane przez fakt, że musimy uzyskać dostęp do nazwy kolumny przy użyciu indeksu ciągu lub indeksu porządkowego. Z drugiej strony silnie typizowane daneTable będą miały każdą z jego kolumn zaimplementowanych jako właściwości, co powoduje, że kod 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ć typów zestawów danych. Obiekt biznesowy jest implementowany przez dewelopera jako klasę, której właściwości zazwyczaj odzwierciedlają kolumny tabeli bazowej bazy danych, którą reprezentuje obiekt biznesowy. Typed DataSet to klasa wygenerowana przez program Visual Studio na podstawie schematu bazy danych i której elementy członkowskie są silnie typizowane zgodnie z tym schematem. Sam typowy zestaw danych składa się z klas, które rozszerzają klasy ADO.NET DataSet, DataTable i DataRow. Oprócz silnie typizowanej tabeli DataTables typy zestawów danych zawierają również klasy TableAdapters, które są klasami do wypełniania tabel DataTables i propagacji modyfikacji w tabelach DataTables z powrotem do bazy danych.

Uwaga

Aby uzyskać więcej informacji na temat zalet i wad używania typowych zestawów danych i niestandardowych obiektów biznesowych, zapoznaj się z tematem Projektowanie składników warstwy danych i przekazywanie danych przez warstwy.

Na potrzeby architektury tych samouczków użyjemy silnie typionych zestawów danych. Rysunek 3 ilustruje przepływ pracy między różnymi warstwami aplikacji, która używa typów zestawów danych.

Cały kod dostępu do danych jest zdegradowany do dal

Rysunek 3. Cały kod dostępu do danych jest zdegradowany do dal (kliknij, aby wyświetlić obraz pełnowymiarowy)

Tworzenie typowego zestawu danych i adaptera tabeli

Aby rozpocząć tworzenie naszego dal, zacznijmy od dodania typu zestawu danych do naszego projektu. Aby to osiągnąć, kliknij prawym przyciskiem myszy węzeł projektu w Eksplorator rozwiązań i wybierz pozycję Dodaj nowy element. Wybierz opcję Zestaw danych z listy szablonów i nadaj jej Northwind.xsdnazwę .

Wybierz, aby dodać nowy zestaw danych do projektu

Rysunek 4. Wybierz pozycję Dodaj nowy zestaw danych do projektu (kliknij, aby wyświetlić obraz pełnowymiarowy)

Po kliknięciu przycisku Dodaj po wyświetleniu monitu o dodanie zestawu danych do App_Code folderu wybierz pozycję Tak. Zostanie wyświetlona Projektant dla typu zestawu danych, a Kreator konfiguracji TableAdapter zostanie uruchomiony, co umożliwi dodanie pierwszej klasy TableAdapter do zestawu danych typowych.

Typd DataSet służy jako silnie typizowana kolekcja danych; Składa się on z silnie typiowanych wystąpień dataTable, z których każdy z kolei składa się z silnie typiowanych wystąpień elementu DataRow. Utworzymy silnie typizowana tabelę DataTable dla każdej z bazowych tabel bazy danych, z którymi musimy pracować w tej serii samouczków. Zacznijmy od utworzenia tabeli DataTable.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 tabela TableAdapter będzie zawierać metody GetProducts(), GetProductByCategoryID(categoryID)i tak dalej, które wywołamy z warstwy prezentacji. Rola elementu DataTable ma służyć jako silnie typizowane obiekty używane do przekazywania danych między warstwami.

Kreator konfiguracji tableAdapter rozpoczyna się od wyświetlenia monitu o wybranie bazy danych do pracy. 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ć.

Wybierz bazę danych Northwind z listy Drop-Down

Rysunek 5. Wybieranie bazy danych Northwind z listy Drop-Down (kliknij, aby wyświetlić obraz pełnowymiarowy)

Po wybraniu bazy danych i kliknięciu przycisku Dalej zostanie wyświetlony monit o zapisanie parametry połączenia w Web.config pliku. Zapisując parametry połączenia należy unikać kodowania go w klasach TableAdapter, co upraszcza elementy, jeśli parametry połączenia zmiany informacji w przyszłości. Jeśli zdecydujesz się zapisać parametry połączenia w pliku konfiguracji, który zostanie umieszczony w <connectionStrings> sekcji, która może być opcjonalnie zaszyfrowana w celu zwiększenia bezpieczeństwa lub modyfikacji później za pomocą nowej strony właściwości ASP.NET 2.0 w narzędziu Administracja graficznym interfejsu użytkownika usług IIS, co jest bardziej idealne dla administratorów.

Zapisz parametry połączenia w Web.config

Rysunek 6. Zapisywanie parametrów połączenia w programie Web.config (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Następnie musimy zdefiniować schemat dla pierwszej silnie typizowanej tabeli DataTable i podać pierwszą metodę, która będzie używana przez metodę 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 do tego zapytania. Po osiągnięciu tego celu tę metodę można wywołać 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 element TableAdapter wystawił zapytanie. Możemy użyć instrukcji ad hoc SQL, utworzyć nową procedurę składowaną lub użyć istniejącej procedury składowanej. Na potrzeby tych samouczków użyjemy instrukcji ad hoc JĘZYKA SQL.

Wykonywanie zapytań dotyczących danych przy użyciu instrukcji SQL ad hoc

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:

Wprowadź zapytanie SQL w polu tekstowym

Rysunek 8. Wprowadź zapytanie SQL w polu tekstowym (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Możesz też użyć konstruktora zapytań i skonstruować je graficznie, jak pokazano na rysunku 9.

Tworzenie zapytania graficznego za pośrednictwem Edytor Power Query

Rysunek 9. Graficzne tworzenie zapytania za pomocą Edytor Power Query (kliknij, aby wyświetlić obraz pełnowymiarowy)

Po utworzeniu zapytania, ale przed przejściem na następny ekran kliknij przycisk Opcje zaawansowane. W projektach witryn sieci Web opcja "Generuj instrukcje Wstaw, Aktualizuj i Usuń" jest jedyną opcją zaawansowaną wybraną domyślnie; Jeśli uruchomisz tego kreatora z biblioteki klas lub projektu systemu Windows, zostanie również wybrana opcja "Użyj 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 samouczkach.

Wybierz opcję Tylko wygeneruj instrukcje Insert, Update i Delete

Rysunek 10. Wybierz opcję Tylko Generuj instrukcje Wstaw, Aktualizuj i Usuń (kliknij, aby wyświetlić obraz pełnowymiarowy)

Po zweryfikowaniu opcji zaawansowanych kliknij przycisk Dalej, aby przejść do ekranu końcowego. W tym miejscu zostanie wyświetlony monit o wybranie metod do dodania do elementu 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 za pomocą metody Fill() .
  • Zwróć tabelę DataTable przy użyciu tej metody, którą metoda tworzy i wypełnia tabelę DataTable, i zwraca ją jako wartość zwracaną przez metody.

Element TableAdapter może implementować jeden lub oba te wzorce. Możesz również zmienić nazwy metod podanych tutaj. Pozostawmy zaznaczone oba pola wyboru, mimo że w tych samouczkach będziemy używać tylko tego ostatniego wzorca. Ponadto zmieńmy nazwę raczej ogólnej GetData metody na GetProducts.

Jeśli to pole wyboru, ostatnie pole wyboru "GenerateDBDirectMethods", tworzy Insert()metody , Update()i Delete() dla elementu TableAdapter. Jeśli ta opcja nie zostanie zaznaczona, wszystkie aktualizacje będą musiały zostać wykonane za pomocą jedynej Update() metody TableAdapter, która przyjmuje typed DataSet, DataTable, pojedynczą wartość DataRow lub tablicę DataRows. (Jeśli usunięto zaznaczenie 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.

Zmień nazwę metody z GetData na GetProducts

Rysunek 11. Zmiana nazwy metody z GetData na GetProducts (kliknij, aby wyświetlić obraz w pełnym rozmiarze)

Zakończ pracę kreatora, klikając przycisk Zakończ. Po zamknięciu kreatora wrócimy do Projektant Zestawu danych, który pokazuje właśnie utworzoną tabelę DataTable. Listę kolumn można wyświetlić w tabeli Products DataTable (ProductID, ProductNameitd.), a także metody ProductsTableAdapter (Fill() i GetProducts()).

Produkty DataTable i ProductsTableAdapter zostały dodane do typizowanego zestawu danych

Rysunek 12. Tabela Products danych i ProductsTableAdapter zostały dodane do typu zestawu danych (kliknij, aby wyświetlić obraz w pełnym rozmiarze)

W tym momencie mamy typowy zestaw danych z jedną tabelą DataTable (Northwind.Products) i silnie typizowanym klasą GetProducts() DataAdapter (NorthwindTableAdapters.ProductsTableAdapter) z metodą . 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 napisania 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 parametrów połączenia, zapytań SQL ani procedur składowanych. Zamiast tego tableAdapter udostępnia kod dostępu do danych niskiego poziomu dla nas.

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 najlepiej ze wszystkimi tabelami DataTable zwracanych przez klasę TableAdapter można powiązać z kontrolkami sieci Web ASP.NET danych, takimi jak GridView, DetailsView, DropDownList, CheckBoxList i kilka innych. Poniższy przykład ilustruje powiązanie elementu DataTable zwróconego przez GetProducts() metodę do kontrolki GridView w zaledwie trzech wierszach kodu w programie obsługi zdarzeń 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

Lista produktów jest wyświetlana w elementy GridView

Rysunek 13. Lista produktów jest wyświetlana w siatce (kliknij, aby wyświetlić obraz pełnowymiarowy)

Chociaż w tym przykładzie napisaliśmy trzy wiersze kodu w procedurze obsługi zdarzeń strony Page_Load ASP.NET, w przyszłych samouczkach sprawdzimy, jak deklaratywnie pobrać dane z dal za pomocą obiektu ObjectDataSource. W przypadku obiektu ObjectDataSource nie będziemy musieli pisać żadnego kodu i będą również otrzymywać 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 określonym 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 klasy TableAdapter.

Dodajmy metodę GetProductsByCategoryID(categoryID) . Aby dodać nową metodę do dal, wróć do Projektant Zestawu danych, kliknij prawym przyciskiem myszy w ProductsTableAdapter sekcji i wybierz polecenie Dodaj zapytanie.

Kliknij prawym przyciskiem myszy element TableAdapter i wybierz polecenie Dodaj zapytanie

Rysunek 14. Right-Click w tabeli TableAdapter i wybierz pozycję 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. Spróbujmy ponownie użyć instrukcji ad hoc SQL. Następnie zostanie wyświetlony monit o typ zapytania SQL, którego chcemy użyć. Ponieważ chcemy zwrócić wszystkie produkty należące do określonej kategorii, chcemy napisać instrukcję zwracającą SELECT wiersze.

Wybierz, aby utworzyć instrukcję SELECT zwracającą 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 tej samej SELECT instrukcji z GetProducts()klasy , ale dodaj następującą WHERE klauzulę: WHERE CategoryID = @CategoryID. Parametr @CategoryID wskazuje kreator TableAdapter, że metoda, którą tworzymy, będzie wymagać parametru wejściowego odpowiedniego typu (czyli liczby całkowitej dopuszczającej wartość null).

Wprowadź zapytanie, aby zwracać tylko produkty w określonej kategorii

Rysunek 16. Wprowadź zapytanie zwracające tylko produkty w określonej kategorii (kliknij, aby wyświetlić obraz pełnowymiarowy)

W ostatnim kroku możemy wybrać wzorce dostępu do danych, które mają być używane, a także dostosować nazwy wygenerowanych metod. W przypadku wzorca Wypełnienia zmieńmy nazwę na FillByCategoryID i dla zwracania wzorca zwracanego w tabeli DataTable ( GetX metody) użyjemy metody GetProductsByCategoryID.

Wybieranie nazw metod TableAdapter

Rysunek 17. Wybieranie nazw metod TableAdapter (kliknij, aby wyświetlić obraz pełnowymiarowy)

Po ukończeniu pracy kreatora zestaw danych Projektant zawiera nowe metody TableAdapter.

Zapytania o produkty można teraz wykonywać według kategorii

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 zestawu danych Projektant. 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.

Te produkty należące do kategorii napojów są wyświetlane

Rysunek 19. Te produkty należące do kategorii Napojów są wyświetlane (kliknij, aby wyświetlić obraz pełnowymiarowy)

GetProductsByCategoryID(categoryID) Za pomocą 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 pokazano wszystkie produkty z kategorii Napoje, które mają CategoryID wartość 1.

Beverages.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

Te produkty w kategorii Napoje są wyświetlane

Rysunek 20. Te produkty w kategorii Napoje są wyświetlane (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 wywołam bezpośredni wzorzec bazy danych, polega na tworzeniu metod, które podczas wywoływania wydać INSERTpolecenie , UPDATElub DELETE do bazy danych, która działa na jednym rekordzie bazy danych. 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 wstawiania, aktualizowania lub usuwania. Na przykład w przypadku tego wzorca dla Products tabeli metoda delete byłaby pobrana w parametrze integer wskazującym ProductID rekord do usunięcia, podczas gdy metoda insert zajęłaby ciąg dla ProductName, liczby dziesiętnej UnitPricedla , liczby całkowitej UnitsOnStockdla , itd.

Każde żądanie wstawiania, aktualizowania i usuwania jest wysyłane natychmiast do bazy danych

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)

Drugi wzorzec, który będę nazywał wzorcem aktualizacji wsadowej, jest zaktualizowanie całego zestawu danych, tabeli DataTable lub kolekcji elementów 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 elementy 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 wysyła odpowiednie żądanie bazy danych dla każdego rekordu.

Wszystkie zmiany są synchronizowane z bazą danych po wywołaniu metody aktualizacji

Rysunek 22. Wszystkie zmiany są synchronizowane z bazą danych po wywołaniu metody aktualizacji (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Metoda TableAdapter domyślnie używa wzorca aktualizacji wsadowej, ale obsługuje również wzorzec bezpośredni bazy danych. Ponieważ podczas tworzenia obiektu TableAdapter została wybrana opcja "Generuj instrukcje Wstaw, Aktualizuj i Usuń" z właściwości zaawansowanych, ProductsTableAdapter element zawiera metodę Update() , która implementuje wzorzec aktualizacji wsadowej. W szczególności tabela TableAdapter zawiera metodę, którą można przekazać typed DataSet, silnie typizowaną tabelę Update() Danych lub jedną lub więcej elementów DataRows. Jeśli pole wyboru "GenerateDBDirectMethods" zostało zaznaczone podczas pierwszego tworzenia obiektu TableAdapter, wzorzec bezpośredni bazy danych zostanie również zaimplementowany za pomocą Insert()metod , Update()i Delete() .

Oba wzorce modyfikacji danych używają właściwości , UpdateCommandi tableAdapter InsertCommanddo wystawiania ich INSERTpoleceń , UPDATEi DELETE do bazy DeleteCommand danych. Możesz sprawdzić i zmodyfikować InsertCommandwłaściwości , UpdateCommandiDeleteCommand, klikając element TableAdapter w Projektant Zestawu danych, a następnie przechodząc do okno Właściwości. (Upewnij się, że wybrano obiekt TableAdapter i że ProductsTableAdapter obiekt jest wybrany na liście rozwijanej w okno Właściwości).

Obiekt TableAdapter ma właściwości InsertCommand, UpdateCommand i DeleteCommand

Rysunek 23. Obiekt TableAdapter ma InsertCommandwłaściwości , UpdateCommandi DeleteCommand (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Aby zbadać lub zmodyfikować dowolne z tych właściwości polecenia bazy danych, kliknij CommandText podwłaściwość, która spowoduje wyświetlenie Konstruktora zapytań.

Konfigurowanie instrukcji INSERT, UPDATE i DELETE w konstruktorze zapytań

Rysunek 24. Konfigurowanie instrukcji INSERT, UPDATEi DELETE w konstruktorze zapytań (kliknij, aby wyświetlić obraz pełnowymiarowy)

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()Metody , Update()i Delete() 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 intelliSense nie jest szczególnie jasne, co Products kolumna tabeli mapuje na każdy parametr wejściowy do Update() metod i Insert() . Czasami chcemy zaktualizować tylko jedną kolumnę lub dwie albo wybrać niestandardową Insert() metodę, która może zwrócić wartość nowo wstawionego rekordu IDENTITY (auto-inkrementacja).

Aby utworzyć taką metodę niestandardową, wróć do Projektant 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 zdecyduj się utworzyć INSERT zapytanie.

Tworzenie metody w celu dodania nowego wiersza do tabeli Products

Rysunek 25. Tworzenie metody w celu dodania nowego wiersza do Products tabeli (kliknij, aby wyświetlić obraz pełnowymiarowy)

Na następnym ekranie pojawi się znak InsertCommand"s CommandText ". Rozszerz to zapytanie, dodając SELECT SCOPE_IDENTITY() na końcu zapytania, co spowoduje zwrócenie ostatniej wartości tożsamości wstawionej do IDENTITY kolumny 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). Przed dodaniem instrukcji SELECT upewnij się, że instrukcja kończy INSERT się średnikiem.

Rozszerzanie zapytania w celu zwrócenia wartości SCOPE_IDENTITY()

Rysunek 26. Rozszerzanie zapytania w celu zwrócenia SCOPE_IDENTITY() wartości (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Na koniec nadaj nowej metodzie InsertProductnazwę .

Ustaw nową nazwę metody na InsertProduct

Rysunek 27. Ustaw nową nazwę metody na InsertProduct (kliknij, aby wyświetlić obraz w pełnym rozmiarze)

Po powrocie do Projektant Zestawu danych zobaczysz, że element ProductsTableAdapter zawiera nową metodę InsertProduct. Jeśli ta nowa metoda nie ma parametru dla każdej kolumny w Products tabeli, prawdopodobieństwo, że nie pamiętasz zakończenia INSERT instrukcji średnikiem. Skonfiguruj metodę InsertProduct i upewnij się, że istnieją średniki rozdzielające instrukcje INSERT i SELECT .

Domyślnie metody wstawiania wystawiają metody inne niż zapytania, co oznacza, że zwracają liczbę wierszy, których dotyczy problem. Chcemy jednak, InsertProduct aby metoda zwróciła wartość zwróconą przez zapytanie, a nie liczbę wierszy, których dotyczy problem. Aby to osiągnąć, dostosuj InsertProduct właściwość metody ExecuteMode do Scalarwartości .

Zmień właściwość ExecuteMode na Skalarną

Rysunek 28. Zmień ExecuteMode właściwość na Scalar (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 Categories tabeli ani CompanyName kolumny z Suppliers tabeli, chociaż są to prawdopodobnie 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 CategoryName wartości kolumn, jak i CompanyName , co spowoduje zaktualizowanie silnie typizowanej tabeli 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 automatyczne metody wstawiania, aktualizowania i usuwania nie mają wpływu na podzapytania w klauzuli SELECT . Dbając o dodanie zapytań do Categories podzapytania i Suppliers jako podzapytania, a nie JOIN do podzapytania, unikamy konieczności przerobienia tych metod na potrzeby modyfikowania danych. Kliknij prawym przyciskiem myszy metodę GetProducts() w pliku 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

Aktualizowanie instrukcji SELECT dla metody GetProducts()

Rysunek 29. Aktualizowanie instrukcji SELECT dla GetProducts() metody (kliknij, aby wyświetlić obraz w pełnym rozmiarze)

Po zaktualizowaniu metody w GetProducts() celu użycia tego nowego zapytania tabela DataTable będzie zawierać dwie nowe kolumny: CategoryName i SupplierName.

Tabela DataTable produktów ma dwie nowe kolumny

Rysunek 30. Tabela Products danych ma dwie nowe kolumny

Poświęć chwilę na zaktualizowanie SELECT klauzuli w metodzie GetProductsByCategoryID(categoryID) .

W przypadku zaktualizowania GetProducts()SELECT składni przy użyciu JOIN Projektant zestaw danych nie będzie mógł automatycznie wygenerować metod wstawiania, aktualizowania i usuwania danych bazy danych przy użyciu wzorca bezpośredniego bazy danych. Zamiast tego musisz ręcznie je utworzyć podobnie jak InsertProduct w przypadku metody wcześniej w tym samouczku. Ponadto należy ręcznie podać InsertCommandwartości właściwości , UpdateCommandi DeleteCommand , jeśli chcesz użyć wzorca aktualizacji wsadowej.

Dodawanie pozostałych elementów TableAdapters

Do tej pory przyjrzeliśmy się tylko pracy z pojedynczą tabelą TableAdapter dla pojedynczej tabeli bazy danych. Jednak baza danych Northwind zawiera kilka powiązanych tabel, z którymi będziemy musieli pracować w naszej aplikacji internetowej. Typowany zestaw danych może zawierać wiele powiązanych tabel Danych. W związku z tym, aby ukończyć dal, musimy dodać tabele DataTable dla innych tabel, których będziemy używać w tych samouczkach. Aby dodać nowy element TableAdapter do typu zestawu danych, otwórz Projektant DataSet, kliknij prawym przyciskiem myszy Projektant, a następnie wybierz polecenie Dodaj/TableAdapter. Spowoduje to utworzenie nowych tabel DataTable i TableAdapter oraz omówienie kreatora, który omówiliśmy wcześniej w tym samouczku.

Poświęć kilka minut, aby utworzyć następujące metody i metody TableAdapters przy użyciu następujących zapytań. Należy pamiętać, że zapytania w podzapytaniu ProductsTableAdapter obejmują podzapytania do przejęcia kategorii i nazw dostawców każdego produktu. Ponadto, jeśli wykonano następujące czynności, dodano ProductsTableAdapter już metody i GetProductsByCategoryID(categoryID) klasy GetProducts() .

  • ProductsTableAdapter

    • GetProducts:

      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
      
    • GetProductsByCategoryID:

      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 = @CategoryID
      
    • GetProductsBySupplierID:

      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 = @SupplierID
      
    • GetProductByProductID:

      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

    • GetCategories:

      SELECT     CategoryID, CategoryName, Description
      FROM         Categories
      
    • GetCategoryByCategoryID:

      SELECT     CategoryID, CategoryName, Description
      FROM         Categories
      WHERE CategoryID = @CategoryID
      
  • SuppliersTableAdapter

    • Pobierz dostawców:

      SELECT     SupplierID, CompanyName, Address,
      City, Country, Phone
      FROM         Suppliers
      
    • GetSuppliersByCountry:

      SELECT     SupplierID, CompanyName, Address,
      City, Country, Phone
      FROM         Suppliers
      WHERE Country = @Country
      
    • GetSupplierBySupplierID:

      SELECT     SupplierID, CompanyName, Address,
      City, Country, Phone
      FROM         Suppliers
      WHERE SupplierID = @SupplierID
      
  • EmployeesTableAdapter

    • GetEmployees:

      SELECT     EmployeeID, LastName, FirstName, Title,
      HireDate, ReportsTo, Country
      FROM         Employees
      
    • GetEmployeesByManager:

      SELECT     EmployeeID, LastName, FirstName, Title, 
      HireDate, ReportsTo, Country
      FROM         Employees
      WHERE ReportsTo = @ManagerID
      
    • GetEmployeeByEmployeeID:

      SELECT     EmployeeID, LastName, FirstName, Title,
      HireDate, ReportsTo, Country
      FROM         Employees
      WHERE EmployeeID = @EmployeeID
      

Zestaw danych Projektant po dodaniu czterech elementów TableAdapters

Rysunek 31. Zestaw danych Projektant Po dodaniu czterech elementów TableAdapters (kliknij, aby wyświetlić obraz pełnowymiarowy)

Dodawanie kodu niestandardowego do dal

Tabele TableAdapters i DataTable dodane do typu zestawu danych są wyrażane jako plik definicji schematu XML (Northwind.xsd). Te informacje o schemacie można wyświetlić, klikając prawym przyciskiem myszy Northwind.xsd plik w Eksplorator rozwiązań i wybierając polecenie Wyświetl kod.

Plik definicji schematu XML (XSD) dla typu Northwinds DataSet

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 niego za pomocą debugera. Aby wyświetlić ten automatycznie wygenerowany kod, przejdź do widoku klasy 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 stamtąd lub naciśnij klawisze Ctrl+Shift+C. W widoku klasy można zobaczyć 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 go prawym przyciskiem myszy i wybierz pozycję Przejdź do definicji.

Sprawdź kod wygenerowany automatycznie, wybierając pozycję Przejdź do definicji z widoku klasy

Rysunek 33. Sprawdzanie wygenerowanego automatycznie kodu przez wybranie pozycji Przejdź do definicji z widoku klasy

Chociaż kod generowany automatycznie może być doskonałym oszczędnością czasu, kod jest często bardzo ogólny i musi być dostosowany do unikatowych potrzeb aplikacji. Ryzyko rozszerzenia wygenerowanego automatycznie 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ąpienie naszych dostosowań przez program Visual Studio.

Aby zademonstrować sposób dostosowywania dal, dodajmy metodę GetProducts() do SuppliersRow klasy. Klasa reprezentuje pojedynczy rekord w Suppliers tabeli. Każdy SuppliersRow dostawca może dostarczyć zero do wielu produktów, dlatego 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 w celu uwzględnienia właśnie zdefiniowanej GetProducts() metody. Jeśli skompilujesz projekt, a następnie powrócisz do widoku klasy, zobaczysz GetProducts() teraz jako metodę Northwind.SuppliersRow.

Metoda GetProducts() jest teraz częścią klasy Northwind.SuppliersRow

Rysunek 34. GetProducts() Metoda jest teraz częścią Northwind.SuppliersRow klasy

Metoda GetProducts() może teraz służyć do wyliczania 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 można również wyświetlić na dowolnej platformie ASP. Kontrolki sieci Web danych platformy NET. Poniższa strona używa kontrolki GridView z dwoma polami:

  • Pole powiązane, które wyświetla nazwę każdego dostawcy i
  • Pole szablonu zawierające kontrolkę BulletedList, która jest powiązana z wynikami zwróconych przez metodę GetProducts() dla każdego dostawcy.

Przeanalizujemy sposób wyświetlania takich raportów master-detail w przyszłych samouczkach. Na razie ten przykład został zaprojektowany w celu zilustrowania użycia metody niestandardowej dodanej Northwind.SuppliersRow do klasy.

SuppliersAndProducts.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

Nazwa firmy dostawcy jest wymieniona w lewej kolumnie, ich produkty po prawej stronie

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 tworzącej dal należy wykonać jeden z pierwszych kroków przed rozpoczęciem tworzenia warstwy prezentacji. W programie Visual Studio tworzenie 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 w przyszłości 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:

Szkolenie wideo dotyczące tematów zawartych w tym samouczku

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 ciągu 24 godzin. Można do niego dotrzeć pod adresem mitchell@4GuysFromRolla.com. Lub za pośrednictwem swojego bloga, który można znaleźć na stronie http://ScottOnWriting.NET.

Specjalne podziękowania

Ta seria samouczków została sprawdzona przez wielu pomocnych recenzentów. Recenzenci w tym samouczku to Ron Green, Hilton Giesenow, Dennis Patterson, Liz Shulok, Abel Gomez i Carlos Santos. Chcesz przejrzeć nadchodzące artykuły MSDN? Jeśli tak, upuść mi wiersz pod adresem mitchell@4GuysFromRolla.com.