Aktualizowanie elementu TableAdapter w celu używania sprzężeń JOIN (VB)
Autor : Scott Mitchell
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 JOIN
s. 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 INSERT
instrukcji , UPDATE
i 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 InsertCommand
właściwości , UpdateCommand
i 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 INSERT
instrukcji , UPDATE
i 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
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 INSERT
instrukcje , UPDATE
i 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ć INSERT
instrukcji , UPDATE
i DELETE
, ponieważ główne zapytanie zawiera JOIN
element .
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.
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 InsertCommand
właściwości , UpdateCommand
i DeleteCommand
. Aby to potwierdzić, kliknij element TableAdapter w Projektant, a następnie przejdź do okno Właściwości. Zobaczysz, że InsertCommand
właściwości , UpdateCommand
i DeleteCommand
są ustawione na wartość (Brak).
Rysunek 4.InsertCommand
Właściwości , UpdateCommand
i 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 InsertCommand
właściwości , UpdateCommand
i 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. INSERT
Pozwoli to automatycznie wygenerować instrukcje , UPDATE
iDELETE
. 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 INSERT
instrukcje , UPDATE
i 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 INSERT
instrukcji , UPDATE
i 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ć SelectCommand
procedury składowane , InsertCommand
, UpdateCommand
lub 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).
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 INSERT
instrukcjami , UPDATE
i 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_Insert
Employees_Update
i Employees_Delete
, jak pokazano na rysunku 6.
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).
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_Insert
Employees_Update
i 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 InsertCommand
właściwości , UpdateCommand
i są DeleteCommand
poprawnie skonfigurowane do wywoływania odpowiednich procedur składowanych.
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 InsertCommand
właściwościach , UpdateCommand
i 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).
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 usunieInsertCommand
również właściwości ,UpdateCommand
iDeleteCommand
, ponieważ terazSelectCommand
zawieraJOIN
element . 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
.
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
.
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 GetEmployees
DeleteEmployee
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.
Rysunek 12. Konfigurowanie obiektu ObjectDataSource do używania EmployeesBLLWithSprocs
klasy (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
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
, FirstName
ManagerFirstName
i 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).
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.
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:
- Zaktualizuj ograniczenie klucza obcego, aby kaskadowo usunąć,
- Ręcznie usuń rekordy z
Orders
tabeli dla pracowników, których chcesz usunąć, lub - Zaktualizuj procedurę składowaną,
Employees_Delete
aby najpierw usunąć powiązane rekordy zOrders
tabeli przed usunięciem rekorduEmployees
. Omówiliśmy tę technikę w samouczku Using Existing Stored Procedures for the Typed DataSet s TableAdapters (Używanie istniejących procedur składowanych dla typów elementów TableAdapters).
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ć INSERT
instrukcji , UPDATE
i 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 JOIN
zapytania -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 .