Aktualizowanie elementu TableAdapter w celu używania sprzężeń JOIN (C#)
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ź EmployeesDataTable
element i EmployeesTableAdapter
właśnie utworzony. Tabela Danych zawiera kolumnę dla każdego pola zwróconego przez zapytanie główne. Kliknij pozycję TableAdapter, a następnie przejdź do okno Właściwości. Zobaczysz, że InsertCommand
właściwości , UpdateCommand
i DeleteCommand
są poprawnie skonfigurowane do wywoływania odpowiednich procedur składowanych.
Rysunek 8. TabelaAdapter zawiera możliwości wstawiania, aktualizowania i usuwania (kliknij, aby wyświetlić obraz pełnowymiarowy)
Dzięki automatycznemu utworzeniu InsertCommand
, aktualizowaniu i usuwaniu procedur składowanych oraz poprawnie skonfigurowanych właściwości , UpdateCommand
i DeleteCommand
możemy dostosować SelectCommand
procedurę składowaną w celu zwrócenia dodatkowych informacji o każdym menedżerze pracownika. W szczególności musimy zaktualizować procedurę Employees_Select
składowaną, aby użyć elementu JOIN
i zwrócić wartości i LastName
menedżeraFirstName
. Po zaktualizowaniu procedury składowanej musimy 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 SELECT
instrukcji zapisz zmiany, przechodząc do menu Plik i wybierając pozycję 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 pełnowymiarowy)
Krok 3. Aktualizowanie kolumn tabeli danych
W tym momencie Employees_Select
procedura składowana zwraca ManagerFirstName
wartości i ManagerLastName
zwraca je, 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 pozycję Kolumna. Następnie możesz nazwać kolumnę i odpowiednio ustawić jej właściwości.
- Automatycznie — kreator konfiguracji tableAdapter zaktualizuje kolumny Tabeli danych, aby odzwierciedlić pola zwrócone przez procedurę
SelectCommand
składowaną. W przypadku korzystania z instrukcji AD-hoc SQL 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.
W poprzednich samouczkach omówiliśmy ręczne dodawanie kolumn DataTable, w tym master /detail Using a Bulleted List of Master Records with a Details DataList and Uploading Files (Tabela danych) i Uploading Files (Tabela danych) i przekażemy pliki, a następnie omówimy ten proces bardziej szczegółowo w następnym samouczku. Na potrzeby tego samouczka użyjemy jednak podejścia automatycznego za pośrednictwem Kreatora konfiguracji tableAdapter.
Zacznij od kliknięcia prawym przyciskiem myszy EmployeesTableAdapter
i wybrania pozycji Konfiguruj z menu kontekstowego. Spowoduje to wyświetlenie kreatora konfiguracji 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. W tym miejscu 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)
Ukończ pracę kreatora, klikając przycisk Zakończ. Po powrocie do zestawu danych Projektant EmployeesDataTable
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 funkcje 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.cs
. Ta klasa naśladuje semantyka istniejącej EmployeesBLL
klasy, tylko ta nowa zapewnia mniej metod i używa NorthwindWithSprocs
zestawu Danych (zamiast Northwind
zestawu danych). Dodaj poniższy kod do klasy EmployeesBLLWithSprocs
.
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using NorthwindWithSprocsTableAdapters;
[System.ComponentModel.DataObject]
public class EmployeesBLLWithSprocs
{
private EmployeesTableAdapter _employeesAdapter = null;
protected EmployeesTableAdapter Adapter
{
get
{
if (_employeesAdapter == null)
_employeesAdapter = new EmployeesTableAdapter();
return _employeesAdapter;
}
}
[System.ComponentModel.DataObjectMethodAttribute
(System.ComponentModel.DataObjectMethodType.Select, true)]
public NorthwindWithSprocs.EmployeesDataTable GetEmployees()
{
return Adapter.GetEmployees();
}
[System.ComponentModel.DataObjectMethodAttribute
(System.ComponentModel.DataObjectMethodType.Delete, true)]
public bool DeleteEmployee(int employeeID)
{
int rowsAffected = Adapter.Delete(employeeID);
// Return true if precisely one row was deleted, otherwise false
return rowsAffected == 1;
}
}
Właściwość EmployeesBLLWithSprocs
klasy zwraca Adapter
wystąpienie elementu NorthwindWithSprocs
DataSet s EmployeesTableAdapter
. Jest to używane przez klasy s GetEmployees
i DeleteEmployee
metody. Metoda GetEmployees
wywołuje odpowiednią GetEmployees
metodęEmployeesTableAdapter
, która wywołuje Employees_Select
procedurę składowaną i wypełnia wyniki w elemecie EmployeeDataTable
. Metoda DeleteEmployee
podobnie wywołuje metodę EmployeesTableAdapter
s Delete
, która wywołuje procedurę Employees_Delete
składowaną.
Krok 5. Praca z danymi w warstwie prezentacji
Po zakończeniu EmployeesBLLWithSprocs
zajęć jesteśmy gotowi do pracy z danymi pracowników za pośrednictwem strony ASP.NET. JOINs.aspx
Otwórz stronę w AdvancedDAL
folderze i przeciągnij kontrolkę GridView z przybornika na 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, aby używać EmployeesBLLWithSprocs
klasy, a następnie na kartach SELECT i DELETE upewnij się, że metody GetEmployees
i DeleteEmployee
zostały wybrane z list rozwijanych. Kliknij przycisk Zakończ, aby ukończyć konfigurację obiektuDataSource.
Rysunek 12. Konfigurowanie obiektu ObjectDataSource do używania EmployeesBLLWithSprocs
klasy (kliknij, aby wyświetlić obraz pełnowymiarowy)
Rysunek 13. Używanie obiektu GetEmployees
ObjectDataSource za pomocą metod i DeleteEmployee
(kliknij, aby wyświetlić obraz pełnowymiarowy)
Program Visual Studio doda pole BoundField do kontrolki GridView dla każdej kolumny EmployeesDataTable
. Usuń wszystkie te pola boundfield z wyjątkiem Title
, , LastName
FirstName
, ManagerFirstName
i ManagerLastName
zmień nazwy HeaderText
właściwości dla ostatnich czterech elementów BoundFields na Last Name, First Name, Manager s First Name i Manager s Last Name, Manager s Last Name( i Manager s Last Name).
Aby umożliwić użytkownikom usuwanie pracowników z tej strony, musimy wykonać dwie czynności. Najpierw poinstruuj element GridView, aby zapewnić możliwości usuwania, sprawdzając opcję Włącz usuwanie z tagu inteligentnego. Po drugie zmień właściwość ObjectDataSource OldValuesParameterFormatString
z wartości ustawionej przez kreatora ObjectDataSource (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 wyświetlać listę poszczególnych pracowników i jego nazwiska kierownika (przy założeniu, że mają jeden).
Rysunek 14. W JOIN
procedurze Employees_Select
składowanej zwraca nazwę menedżera (kliknij, aby wyświetlić obraz pełnowymiarowy)
Kliknięcie przycisku Usuń powoduje uruchomienie przepływu pracy usuwania, który kończy się wykonaniem Employees_Delete
procedury składowanej. Jednak próba instrukcji w procedurze składowanej DELETE
kończy się niepowodzeniem z powodu naruszenia ograniczeń klucza obcego (patrz Rysunek 15). W szczególności każdy pracownik ma co najmniej jeden rekord w Orders
tabeli, powodując niepowodzenie usuwania.
Rysunek 15. Usuwanie pracownika z odpowiednimi zamówieniami powoduje naruszenie ograniczenia klucza obcego (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Aby umożliwić usunięcie pracownika, możesz:
- Zaktualizuj ograniczenie klucza obcego w celu usunięcia kaskadowego,
- Ręcznie usuń rekordy z
Orders
tabeli dla pracowników, które 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 zestawów danych TableAdapters ).
Zostawię to jako ćwiczenie dla czytelnika.
Podsumowanie
Podczas pracy z relacyjnymi bazami danych często zdarza się, że zapytania pobierają dane z wielu powiązanych tabel. Skorelowane podquery i JOIN
s zapewniają dwie różne techniki uzyskiwania dostępu do danych z powiązanych tabel w zapytaniu. W poprzednich samouczkach najczęściej używaliśmy skorelowanych podquerii, ponieważ narzędzie 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 działania kreatora konfiguracji tableAdapter.
Na szczęście klasy TableAdapters utworzone przy użyciu procedur składowanych nie cierpią z powodu tej samej kruchości, co 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 obiektu JOIN
podczas korzystania z procedur składowanych. W tym samouczku pokazano, jak utworzyć taki element TableAdapter. Zaczęliśmy korzystać z JOIN
zapytania -less SELECT
dla głównego zapytania TableAdapter, aby odpowiednie procedury składowane wstawiania, aktualizowania i usuwania zostały automatycznie utworzone. Po zakończeniu początkowej konfiguracji tableAdapter rozszerzyliśmy SelectCommand
procedurę składowaną, aby użyć JOIN
kreatora konfiguracji TableAdapter i ponownie uruchomić go, aby zaktualizować EmployeesDataTable
kolumny.
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 .