Udostępnij za pośrednictwem


Aktualizowanie elementu TableAdapter w celu używania sprzężeń JOIN (VB)

Autor : Scott Mitchell

Pobierz plik PDF

Podczas pracy z bazą danych często żąda się danych rozmieszczonych w wielu tabelach. Aby pobrać dane z dwóch różnych tabel, możemy użyć skorelowanego podzapytania lub operacji JOIN. W tym samouczku porównaliśmy skorelowane podzapytania i składnię JOIN przed sprawdzeniem, jak utworzyć element TableAdapter zawierający element JOIN w zapytaniu głównym.

Wprowadzenie

W przypadku relacyjnych baz danych dane, z którymi jesteśmy zainteresowani, często są rozłożone na wiele tabel. Na przykład podczas wyświetlania informacji o produkcie prawdopodobnie chcemy wyświetlić listę poszczególnych produktów odpowiadających im kategorii i nazw dostawców. Tabela Products zawiera CategoryID wartości i SupplierID , ale rzeczywista kategoria i nazwy dostawców znajdują się odpowiednio w Categories tabelach i Suppliers .

Aby pobrać informacje z innej, powiązanej tabeli, możemy użyć skorelowanych podzapytania lub JOINs. Skorelowane podzapytanie to zapytanie zagnieżdżone SELECT , które odwołuje się do kolumn w zapytaniu zewnętrznym. Na przykład w samouczku Tworzenie warstwy dostępu do danych użyliśmy dwóch skorelowanych podzapytania w ProductsTableAdapter głównym zapytaniu, aby zwrócić kategorię i nazwy dostawców dla każdego produktu. A JOIN to konstrukcja SQL, która scala powiązane wiersze z dwóch różnych tabel. Użyliśmy JOIN elementu w samouczku Dotyczącym wykonywania zapytań o dane za pomocą kontrolki SqlDataSource , aby wyświetlić informacje o kategorii obok każdego produktu.

Powodem, dla którego wstrzymaliśmy się od używania elementów JOIN s z elementami TableAdapters, jest ograniczenie w kreatorze tableAdapter do automatycznego generowania odpowiednich INSERTinstrukcji , UPDATEi DELETE . Mówiąc dokładniej, jeśli główne zapytanie tableAdapter zawiera jakiekolwiek JOIN s, tableAdapter nie może automatycznie utworzyć ad hoc instrukcji SQL lub procedur składowanych dla jego InsertCommandwłaściwości , UpdateCommandi DeleteCommand .

W tym samouczku krótko porównamy skorelowane podzapytania i JOIN s przed zbadaniem, jak utworzyć element TableAdapter zawierający JOIN s w zapytaniu głównym.

Porównywanie i kontrastowanie skorelowanych podzapytania iJOIN s

Pamiętaj, że utworzony ProductsTableAdapter w pierwszym samouczku w zestawie Northwind danych używa skorelowanych podzapytania w celu przywrócenia odpowiadającej im kategorii i nazwy dostawcy każdego produktu. Poniżej ProductsTableAdapter przedstawiono główne zapytanie.

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

Dwa skorelowane podzapytania — (SELECT CategoryName FROM Categories WHERE Categories.CategoryID = Products.CategoryID) i — to SELECT zapytania, które zwracają pojedynczą wartość na produkt jako dodatkową kolumnę na liście kolumn instrukcji zewnętrznej SELECT(SELECT CompanyName FROM Suppliers WHERE Suppliers.SupplierID = Products.SupplierID) .

Alternatywnie JOIN można użyć elementu do zwrócenia nazwy dostawcy i kategorii każdego produktu. Następujące zapytanie zwraca te same dane wyjściowe co powyższe, ale używa JOIN wartości s zamiast podzapytania:

SELECT ProductID, ProductName, Products.SupplierID, Products.CategoryID, 
       QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder, 
       ReorderLevel, Discontinued,
       Categories.CategoryName, 
       Suppliers.CompanyName as SupplierName
FROM Products
    LEFT JOIN Categories ON
        Categories.CategoryID = Products.CategoryID
    LEFT JOIN Suppliers ON
        Suppliers.SupplierID = Products.SupplierID

Rekordy JOIN z jednej tabeli są scalane z rekordami z innej tabeli na podstawie niektórych kryteriów. Na przykład LEFT JOIN Categories ON Categories.CategoryID = Products.CategoryID w powyższym zapytaniu polecenie nakazuje SQL Server scalenie każdego rekordu produktu z rekordem kategorii, którego CategoryID wartość jest zgodna z wartością CategoryID produktu. Scalony wynik umożliwia pracę z odpowiednimi polami kategorii dla każdego produktu (na przykład CategoryName).

Uwaga

JOIN s są często używane podczas wykonywania zapytań dotyczących danych z relacyjnych baz danych. Jeśli jesteś nowym użytkownikiem JOIN składni lub musisz nieco odświeżyć jego użycie, polecam samouczek dołączania SQL w szkołach W3. Warto również przeczytać sekcjeJOIN Podstawy i Podstawy podzapytaniaksiążek SQL Online.

Ponieważ JOIN s i skorelowane podzapytania mogą służyć do pobierania powiązanych danych z innych tabel, wielu deweloperów pozostawia podstawy i zastanawia się, które podejście do użycia. Wszyscy guru SQL, z którymi rozmawiałem, powiedzieli mniej więcej to samo, że tak naprawdę nie ma znaczenia wydajność mądry, jak SQL Server będzie produkować mniej więcej identyczne plany wykonania. Ich porady, a następnie, jest użycie techniki, z którą ty i Twój zespół są najbardziej wygodne. Warto zauważyć, że po przekazaniu tej porady ci eksperci natychmiast wyrazić swoje preferencje co do JOIN skorelowanych podzapytania.

Podczas tworzenia warstwy dostępu do danych przy użyciu typów zestawów danych narzędzia działają lepiej podczas korzystania z podzapytania. W szczególności kreator tableAdapter nie wygeneruje automatycznie odpowiednich INSERTinstrukcji , UPDATEi DELETE , jeśli główne zapytanie zawiera jakiekolwiek JOIN s, ale automatycznie wygeneruje te instrukcje, gdy używane są skorelowane podzapytania.

Aby zapoznać się z tym niedoborem, utwórz tymczasowy zestaw danych typu w folderze ~/App_Code/DAL . W kreatorze konfiguracji tableAdapter wybierz użycie instrukcji AD-hoc SQL i wprowadź następujące SELECT zapytanie (zobacz Rysunek 1):

SELECT ProductID, ProductName, Products.SupplierID, Products.CategoryID, 
       QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder, 
       ReorderLevel, Discontinued,
       Categories.CategoryName, 
       Suppliers.CompanyName as SupplierName
FROM Products
    LEFT JOIN Categories ON
        Categories.CategoryID = Products.CategoryID
    LEFT JOIN Suppliers ON
        Suppliers.SupplierID = Products.SupplierID

Zrzut ekranu przedstawiający okno Kreator konfiguracji narzędzia TableAdaptor z wprowadzonym zapytaniem zawierającym numery JOIN.

Rysunek 1. Wprowadź główne zapytanie zawierające JOIN s (kliknij, aby wyświetlić obraz w pełnym rozmiarze)

Domyślnie narzędzie TableAdapter automatycznie tworzy INSERTinstrukcje , UPDATEi DELETE na podstawie głównego zapytania. Jeśli klikniesz przycisk Zaawansowane, zobaczysz, że ta funkcja jest włączona. Pomimo tego ustawienia funkcja TableAdapter nie będzie mogła utworzyć INSERTinstrukcji , UPDATEi DELETE , ponieważ główne zapytanie zawiera JOINelement .

Zrzut ekranu przedstawiający okno Opcje zaawansowane z zaznaczonym polem wyboru Generuj instrukcje Wstaw, Aktualizuj i Usuń.

Rysunek 2. Wprowadź główne zapytanie zawierające s JOIN

Kliknij przycisk Zakończ, aby zakończyć kreatora. W tym momencie Projektant zestawu danych będzie zawierać jeden element TableAdapter z tabelą DataTable z kolumnami dla każdego pola zwróconego na SELECT liście kolumn zapytania. Obejmuje to elementy i SupplierName, jak pokazano na rysunku CategoryName 3.

Tabela DataTable zawiera kolumnę dla każdego pola zwróconego na liście kolumn

Rysunek 3. Tabela danych zawiera kolumnę dla każdego pola zwróconego na liście kolumn

Chociaż tabela DataTable zawiera odpowiednie kolumny, element TableAdapter nie ma wartości dla jej InsertCommandwłaściwości , UpdateCommandi DeleteCommand . Aby to potwierdzić, kliknij element TableAdapter w Projektant, a następnie przejdź do okno Właściwości. Zobaczysz, że InsertCommandwłaściwości , UpdateCommandi DeleteCommand są ustawione na wartość (Brak).

Właściwości InsertCommand, UpdateCommand i DeleteCommand są ustawione na (Brak)

Rysunek 4.InsertCommand Właściwości , UpdateCommandi DeleteCommand mają ustawioną wartość (Brak) (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Aby obejść ten brak, możemy ręcznie podać instrukcje SQL i parametry dla InsertCommandwłaściwości , UpdateCommandi DeleteCommand za pośrednictwem okno Właściwości. Alternatywnie można rozpocząć od skonfigurowania głównego zapytania tableAdapter, aby nie uwzględniać żadnych JOIN s. INSERTPozwoli to automatycznie wygenerować instrukcje , UPDATEiDELETE. Po ukończeniu pracy kreatora można ręcznie zaktualizować tabelę TableAdapter z SelectCommand okno Właściwości tak, aby zawierała składnięJOIN.

To podejście działa, ale jest bardzo kruche w przypadku korzystania z zapytań SQL ad hoc, ponieważ za każdym razem, gdy główne zapytanie tableAdapter jest ponownie skonfigurowane za pośrednictwem kreatora, automatycznie generowane INSERTinstrukcje , UPDATEi DELETE są odtwarzane. Oznacza to, że wszystkie wprowadzone później dostosowania zostaną utracone, jeśli klikniemy prawym przyciskiem myszy element TableAdapter, wybierz polecenie Konfiguruj z menu kontekstowego i ponownie zakończymy pracę kreatora.

Kruchość automatycznie generowanych INSERTinstrukcji , UPDATEi DELETE funkcji TableAdapter jest na szczęście ograniczona do instrukcji ad hoc JĘZYKA SQL. Jeśli narzędzie TableAdapter używa procedur składowanych, można dostosować SelectCommandprocedury składowane , InsertCommand, UpdateCommandlub DeleteCommand i ponownie uruchomić kreatora konfiguracji tableAdapter bez obawy, że procedury składowane zostaną zmodyfikowane.

W kolejnych kilku krokach utworzymy obiekt TableAdapter, który początkowo używa głównego zapytania, które pomija dowolne JOIN s, aby odpowiednie procedury składowane wstawiania, aktualizowania i usuwania zostały wygenerowane automatycznie. Następnie zaktualizujemy element SelectCommand tak, aby używał elementu zwracającego JOIN dodatkowe kolumny z powiązanych tabel. Na koniec utworzymy odpowiednią klasę warstwy logiki biznesowej i pokażemy użycie klasy TableAdapter na stronie internetowej ASP.NET.

Krok 1. Tworzenie obiektu TableAdapter przy użyciu uproszczonego zapytania głównego

Na potrzeby tego samouczka dodamy tabelę TableAdapter i silnie typizowany element DataTable dla Employees tabeli w zestawie NorthwindWithSprocs danych. Tabela Employees zawiera ReportsTo pole, które określiło EmployeeID menedżera pracownika. Na przykład pracownik Anne Dodsworth ma ReportTo wartość 5, czyli EmployeeID Steven Buchanan. W związku z tym Anne zgłasza Stevenowi, swojemu menedżerowi. Oprócz raportowania ReportsTo wartości każdego pracownika możemy również pobrać nazwę swojego menedżera. Można to zrobić przy użyciu elementu JOIN. Jednak użycie elementu JOIN podczas początkowego tworzenia obiektu TableAdapter uniemożliwia kreatorowi automatyczne generowanie odpowiednich funkcji wstawiania, aktualizowania i usuwania. W związku z tym zaczniemy od utworzenia obiektu TableAdapter, którego główne zapytanie nie zawiera żadnych JOIN s. Następnie w kroku 2 zaktualizujemy główną procedurę składowaną zapytania, aby pobrać nazwę menedżera za pośrednictwem .JOIN

Rozpocznij od otwarcia elementu NorthwindWithSprocs DataSet w folderze ~/App_Code/DAL . Kliknij prawym przyciskiem myszy Projektant, wybierz opcję Dodaj z menu kontekstowego i wybierz element menu TableAdapter. Spowoduje to uruchomienie kreatora konfiguracji narzędzia TableAdapter. Jak pokazano na rysunku 5, kreator utworzy nowe procedury składowane i kliknij przycisk Dalej. Aby zapoznać się z modułem odświeżania podczas tworzenia nowych procedur składowanych z poziomu kreatora tableAdapter, zapoznaj się z samouczkiem Creating New Stored Procedures for the Typed DataSet s TableAdapters (Tworzenie nowych procedur składowanych dla typów elementów TableAdapters).

Wybierz opcję Utwórz nowe procedury składowane

Rysunek 5. Wybierz opcję Utwórz nowe procedury składowane (kliknij, aby wyświetlić obraz pełnowymiarowy)

Użyj następującej SELECT instrukcji dla głównego zapytania tableAdapter:

SELECT EmployeeID, LastName, FirstName, Title, HireDate, ReportsTo, Country
FROM Employees

Ponieważ to zapytanie nie zawiera żadnych JOIN elementów, kreator tableAdapter automatycznie utworzy procedury składowane z odpowiednimi INSERTinstrukcjami , UPDATEi DELETE , a także procedurą składowaną do wykonywania zapytania głównego.

Poniższy krok umożliwia nadenie nam nazwy procedur składowanych tableAdapter. Użyj nazw Employees_Select, , Employees_InsertEmployees_Updatei Employees_Delete, jak pokazano na rysunku 6.

Nazwij procedury składowane tableAdapter

Rysunek 6. Nadaj nazwę procedur składowanych tableAdapter (kliknij, aby wyświetlić obraz w pełnym rozmiarze)

W ostatnim kroku zostanie wyświetlony monit o nadenie nazwy metod tableAdapter. Użyj metod Fill i GetEmployees jako nazw metod. Pamiętaj również, aby pozostawić pole wyboru Create methods to send updates directly to the database (GenerateDBDirectMethods) (Tworzenie metod wysyłania aktualizacji bezpośrednio do bazy danych (GenerateDBDirectMethods).

Nazwij metody TableAdapter s Fill i GetEmployees

Rysunek 7. Nadaj metodom Fill metody TableAdapter i GetEmployees (kliknij, aby wyświetlić obraz pełnowymiarowy)

Po ukończeniu pracy kreatora poświęć chwilę na sprawdzenie procedur składowanych w bazie danych. Powinny zostać wyświetlone cztery nowe: Employees_Select, , Employees_InsertEmployees_Updatei Employees_Delete. Następnie sprawdź element EmployeesDataTable i EmployeesTableAdapter właśnie utworzony. Tabela DataTable zawiera kolumnę dla każdego pola zwróconego przez zapytanie główne. Kliknij element TableAdapter, a następnie przejdź do okno Właściwości. Zobaczysz, że InsertCommandwłaściwości , UpdateCommandi są DeleteCommand poprawnie skonfigurowane do wywoływania odpowiednich procedur składowanych.

Funkcja TableAdapter obejmuje możliwości wstawiania, aktualizowania i usuwania

Rysunek 8. TabelaAdapter zawiera funkcje wstawiania, aktualizowania i usuwania (kliknij, aby wyświetlić obraz w pełnym rozmiarze)

Po automatycznym utworzeniu, zaktualizowaniu i usunięciu procedur składowanych oraz InsertCommandwłaściwościach , UpdateCommandi DeleteCommand możemy dostosować SelectCommand procedurę składowaną, aby zwrócić dodatkowe informacje o każdym menedżerze pracowników. W szczególności musimy zaktualizować procedurę Employees_Select składowaną, aby użyć i JOIN zwrócić wartości i LastName menedżeraFirstName. Po zaktualizowaniu procedury składowanej należy zaktualizować tabelę DataTable, aby zawierała te dodatkowe kolumny. Zajmiemy się tymi dwoma zadaniami w krokach 2 i 3.

Krok 2. Dostosowywanie procedury składowanej w celu uwzględnienia elementuJOIN

Zacznij od przechodzenia do Eksploratora serwera, przechodzenia do szczegółów folderu Procedury składowane bazy danych Northwind i otwierania Employees_Select procedury składowanej. Jeśli ta procedura składowana nie jest widoczna, kliknij prawym przyciskiem myszy folder Procedury składowane i wybierz polecenie Odśwież. Zaktualizuj procedurę składowaną, aby używała elementu , LEFT JOIN aby zwrócić imię i nazwisko menedżera:

SELECT Employees.EmployeeID, Employees.LastName, 
       Employees.FirstName, Employees.Title, 
       Employees.HireDate, Employees.ReportsTo, 
       Employees.Country,
       Manager.FirstName as ManagerFirstName, 
       Manager.LastName as ManagerLastName
FROM Employees
    LEFT JOIN Employees AS Manager ON
        Employees.ReportsTo = Manager.EmployeeID

Po zaktualizowaniu instrukcji SELECT zapisz zmiany, przechodząc do menu Plik i wybierając polecenie Zapisz Employees_Select. Alternatywnie możesz kliknąć ikonę Zapisz na pasku narzędzi lub nacisnąć klawisze Ctrl+S. Po zapisaniu zmian kliknij prawym przyciskiem myszy procedurę Employees_Select składowaną w Eksploratorze serwera i wybierz polecenie Wykonaj. Spowoduje to uruchomienie procedury składowanej i wyświetlenie wyników w oknie Dane wyjściowe (zobacz Rysunek 9).

Wyniki procedur składowanych są wyświetlane w oknie danych wyjściowych

Rysunek 9. Wyniki procedur składowanych są wyświetlane w oknie danych wyjściowych (kliknij, aby wyświetlić obraz w pełnym rozmiarze)

Krok 3. Aktualizowanie kolumn tabeli DataTable

W tym momencie Employees_Select procedura składowana zwraca ManagerFirstName wartości i ManagerLastName , ale EmployeesDataTable brakuje tych kolumn. Te brakujące kolumny można dodać do tabeli DataTable na jeden z dwóch sposobów:

  • Ręcznie — kliknij prawym przyciskiem myszy tabelę DataTable w zestawie danych Projektant, a następnie z menu Dodaj wybierz polecenie Kolumna. Następnie możesz nazwać kolumnę i odpowiednio ustawić jej właściwości.
  • Automatycznie — kreator konfiguracji tableAdapter zaktualizuje kolumny tabeli DataTable w celu odzwierciedlenia pól zwracanych przez procedurę SelectCommand składowaną. W przypadku korzystania z instrukcji SQL ad hoc kreator usunie InsertCommandrównież właściwości , UpdateCommandi DeleteCommand , ponieważ teraz SelectCommand zawiera JOINelement . Jednak w przypadku korzystania z procedur składowanych te właściwości polecenia pozostają nienaruszone.

Omówiliśmy ręczne dodawanie kolumn DataTable w poprzednich samouczkach, w tym master /detail Using a Bulleted List of Master Records with a Details DataList and Uploading Files (Tabela danych Szczegółów z listą danych szczegółów i przekazywaniem plików), a następnie ponownie przyjrzymy się temu procesowi bardziej szczegółowo w następnym samouczku. Jednak w tym samouczku użyjemy podejścia automatycznego za pośrednictwem Kreatora konfiguracji narzędzia TableAdapter.

Zacznij od kliknięcia prawym przyciskiem myszy EmployeesTableAdapter i wybrania pozycji Konfiguruj z menu kontekstowego. Spowoduje to wyświetlenie kreatora konfiguracji narzędzia TableAdapter, który zawiera listę procedur składowanych używanych do wybierania, wstawiania, aktualizowania i usuwania oraz zwracanych wartości i parametrów (jeśli istnieją). Rysunek 10 przedstawia tego kreatora. Tutaj widać, że Employees_Select procedura składowana zwraca ManagerFirstName teraz pola i ManagerLastName .

Kreator wyświetla zaktualizowaną listę kolumn dla procedury składowanej Employees_Select

Rysunek 10. Kreator przedstawia zaktualizowaną listę kolumn dla Employees_Select procedury składowanej (kliknij, aby wyświetlić obraz pełnowymiarowy)

Zakończ pracę kreatora, klikając przycisk Zakończ. Po powrocie do Projektant EmployeesDataTable Zestawu danych element zawiera dwie dodatkowe kolumny: ManagerFirstName i ManagerLastName.

Tabela EmployeesDataTable zawiera dwie nowe kolumny

Rysunek 11. Zawiera EmployeesDataTable dwie nowe kolumny (kliknij, aby wyświetlić obraz pełnowymiarowy)

Aby zilustrować, że zaktualizowana Employees_Select procedura składowana jest w życie i że możliwości wstawiania, aktualizowania i usuwania obiektu TableAdapter są nadal funkcjonalne, utwórzmy stronę internetową, która umożliwia użytkownikom wyświetlanie i usuwanie pracowników. Przed utworzeniem takiej strony musimy jednak najpierw utworzyć nową klasę w warstwie logiki biznesowej do pracy z pracownikami z zestawu NorthwindWithSprocs danych. W kroku 4 utworzymy klasę EmployeesBLLWithSprocs . W kroku 5 użyjemy tej klasy na stronie ASP.NET.

Krok 4. Implementowanie warstwy logiki biznesowej

Utwórz nowy plik klasy w folderze ~/App_Code/BLL o nazwie EmployeesBLLWithSprocs.vb. Ta klasa naśladuje semantyka istniejącej EmployeesBLL klasy. Tylko ta nowa klasa udostępnia mniej metod i używa NorthwindWithSprocs elementu DataSet (zamiast Northwind zestawu danych). Dodaj poniższy kod do klasy EmployeesBLLWithSprocs.

Imports NorthwindWithSprocsTableAdapters
<System.ComponentModel.DataObject()> _
Public Class EmployeesBLLWithSprocs
    Private _employeesAdapter As EmployeesTableAdapter = Nothing
    Protected ReadOnly Property Adapter() As EmployeesTableAdapter
        Get
            If _employeesAdapter Is Nothing Then
                _employeesAdapter = New EmployeesTableAdapter()
            End If
            Return _employeesAdapter
        End Get
    End Property
    <System.ComponentModel.DataObjectMethodAttribute _
        (System.ComponentModel.DataObjectMethodType.Select, True)> _
    Public Function GetEmployees() As NorthwindWithSprocs.EmployeesDataTable
        Return Adapter.GetEmployees()
    End Function
    <System.ComponentModel.DataObjectMethodAttribute _
        (System.ComponentModel.DataObjectMethodType.Delete, True)> _
    Public Function DeleteEmployee(ByVal employeeID As Integer) As Boolean
        Dim rowsAffected = Adapter.Delete(employeeID)
        'Return true if precisely one row was deleted, otherwise false
        Return rowsAffected = 1
    End Function
End Class

Właściwość EmployeesBLLWithSprocs klasy Adapter zwraca wystąpienie elementu NorthwindWithSprocs DataSet s EmployeesTableAdapter. Jest to używane przez klasy i GetEmployeesDeleteEmployee metody. Metoda GetEmployees wywołuje EmployeesTableAdapter odpowiednią GetEmployees metodę , która wywołuje Employees_Select procedurę składowaną i wypełnia wyniki w obiekcie EmployeeDataTable. Metoda DeleteEmployee podobnie wywołuje metodę EmployeesTableAdapter s Delete , która wywołuje procedurę składowaną Employees_Delete .

Krok 5. Praca z danymi w warstwie prezentacji

Po zakończeniu EmployeesBLLWithSprocs zajęć możemy pracować z danymi pracowników za pośrednictwem strony ASP.NET. JOINs.aspx Otwórz stronę w folderze AdvancedDAL i przeciągnij kontrolkę GridView z przybornika do Projektant, ustawiając jej ID właściwość na Employees. Następnie z tagu inteligentnego GridView powiąż siatkę z nową kontrolką ObjectDataSource o nazwie EmployeesDataSource.

Skonfiguruj obiekt ObjectDataSource do używania EmployeesBLLWithSprocs klasy , a na kartach SELECT i DELETE upewnij się, że GetEmployees z list rozwijanych wybrano metody i .DeleteEmployee Kliknij przycisk Zakończ, aby ukończyć konfigurację obiektu ObjectDataSource.

Konfigurowanie obiektu ObjectDataSource do używania klasy EmployeesBLLWithSprocs

Rysunek 12. Konfigurowanie obiektu ObjectDataSource do używania EmployeesBLLWithSprocs klasy (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Używanie metod GetEmployees i DeleteEmployeee objectDataSource

Rysunek 13. Korzystanie z obiektu ObjectDataSource przy GetEmployees użyciu metod i DeleteEmployee (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Program Visual Studio doda pole BoundField do kontrolki GridView dla każdej kolumny EmployeesDataTable . Usuń wszystkie te pola powiązane z wyjątkiem Title, , LastName, FirstNameManagerFirstNamei ManagerLastName zmień nazwy HeaderText właściwości dla ostatnich czterech pól BoundField na Last Name, First Name, Manager s First Name i Manager s Last Name, odpowiednio.

Aby umożliwić użytkownikom usuwanie pracowników z tej strony, musimy wykonać dwie czynności. Najpierw poinstruuj obiekt GridView, aby zapewnić możliwości usuwania, zaznaczając opcję Włącz usuwanie z tagu inteligentnego. Po drugie zmień właściwość ObjectDataSource z wartości ustawionej przez kreatora ObjectDataSource OldValuesParameterFormatString (original_{0}) na wartość domyślną ({0}). Po wprowadzeniu tych zmian znaczniki deklaratywne gridView i ObjectDataSource powinny wyglądać podobnie do następujących:

<asp:GridView ID="Employees" runat="server" AutoGenerateColumns="False" 
    DataKeyNames="EmployeeID" DataSourceID="EmployeesDataSource">
    <Columns>
        <asp:CommandField ShowDeleteButton="True" />
        <asp:BoundField DataField="Title" 
            HeaderText="Title" 
            SortExpression="Title" />
        <asp:BoundField DataField="LastName" 
            HeaderText="Last Name" 
            SortExpression="LastName" />
        <asp:BoundField DataField="FirstName" 
            HeaderText="First Name" 
            SortExpression="FirstName" />
        <asp:BoundField DataField="ManagerFirstName" 
            HeaderText="Manager's First Name" 
            SortExpression="ManagerFirstName" />
        <asp:BoundField DataField="ManagerLastName" 
            HeaderText="Manager's Last Name" 
            SortExpression="ManagerLastName" />
    </Columns>
</asp:GridView>
<asp:ObjectDataSource ID="EmployeesDataSource" runat="server" 
    DeleteMethod="DeleteEmployee" OldValuesParameterFormatString="{0}" 
    SelectMethod="GetEmployees" TypeName="EmployeesBLLWithSprocs">
    <DeleteParameters>
        <asp:Parameter Name="employeeID" Type="Int32" />
    </DeleteParameters>
</asp:ObjectDataSource>

Przetestuj stronę, odwiedzając ją za pośrednictwem przeglądarki. Jak pokazano na rysunku 14, strona będzie zawierać listę wszystkich pracowników i jego nazwiska menedżera (przy założeniu, że mają jeden).

Funkcja JOIN w procedurze składowanej Employees_Select zwraca nazwę menedżera

Rysunek 14. Obiekt JOIN w procedurze Employees_Select składowanej zwraca nazwę menedżera (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Kliknięcie przycisku Usuń powoduje uruchomienie przepływu pracy usuwania, który kończy się wykonywaniem Employees_Delete procedury składowanej. Jednak próba instrukcji w procedurze składowanej DELETE kończy się niepowodzeniem z powodu naruszenia ograniczenia klucza obcego (zobacz Rysunek 15). W szczególności każdy pracownik ma co najmniej jeden rekord w Orders tabeli, co powoduje niepowodzenie usuwania.

Usuwanie pracownika, który ma odpowiednie zamówienia, powoduje naruszenie ograniczenia klucza obcego

Rysunek 15. Usuwanie pracownika z odpowiednimi zamówieniami powoduje naruszenie ograniczenia klucza obcego (kliknij, aby wyświetlić obraz pełnego rozmiaru)

Aby umożliwić usunięcie pracownika, możesz:

Zostawię to jako ćwiczenie dla czytelnika.

Podsumowanie

Podczas pracy z relacyjnymi bazami danych często zapytania pobierają dane z wielu powiązanych tabel. Skorelowane podzapytania i JOIN udostępniają dwie różne techniki uzyskiwania dostępu do danych z powiązanych tabel w zapytaniu. W poprzednich samouczkach najczęściej używaliśmy skorelowanych podzapytania, ponieważ funkcja TableAdapter nie może automatycznie generować INSERTinstrukcji , UPDATEi DELETE dla zapytań obejmujących JOIN s. Chociaż te wartości można podać ręcznie, w przypadku korzystania z instrukcji ad hoc SQL wszelkie dostosowania zostaną zastąpione po zakończeniu pracy kreatora konfiguracji narzędzia TableAdapter.

Na szczęście klasy TableAdapters utworzone przy użyciu procedur składowanych nie mają takiej samej kruchości, jak te utworzone przy użyciu instrukcji AD-hoc SQL. W związku z tym można utworzyć obiekt TableAdapter, którego główne zapytanie używa JOIN obiektu w przypadku korzystania z procedur składowanych. W tym samouczku pokazano, jak utworzyć taki element TableAdapter. Zaczęliśmy od użycia JOINzapytania -less SELECT dla głównego zapytania tableAdapter, aby odpowiednie procedury składowane wstawiania, aktualizowania i usuwania zostałyby automatycznie utworzone. Po zakończeniu konfiguracji początkowej narzędzia TableAdapter rozszerzyliśmy SelectCommand procedurę składowaną, aby użyć JOIN kreatora konfiguracji tableAdapter i ponownie uruchomić go w celu zaktualizowania EmployeesDataTable kolumn s.

Ponowne uruchomienie kreatora konfiguracji tableAdapter automatycznie zaktualizowało EmployeesDataTable kolumny w celu odzwierciedlenia pól danych zwracanych przez procedurę Employees_Select składowaną. Alternatywnie można było ręcznie dodać te kolumny do tabeli DataTable. W następnym samouczku omówimy ręczne dodawanie kolumn do tabeli DataTable.

Szczęśliwe programowanie!

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 przejrzyona przez wielu przydatnych recenzentów. Głównymi recenzentami tego samouczka byli Hilton Geisenow, David Suru i Teresa Murphy. Chcesz przejrzeć nadchodzące artykuły MSDN? Jeśli tak, upuść mi wiersz pod adresemmitchell@4GuysFromRolla.com .