Dodawanie dodatkowych kolumn tabeli DataTable (C#)
W przypadku korzystania z Kreatora tableAdapter do utworzenia typu zestawu danych odpowiedni obiekt DataTable zawiera kolumny zwrócone przez główne zapytanie bazy danych. Istnieją jednak sytuacje, w których tabela DataTable musi zawierać dodatkowe kolumny. W tym samouczku dowiesz się, dlaczego procedury składowane są zalecane, gdy potrzebujemy dodatkowych kolumn dataTable.
Wprowadzenie
Podczas dodawania elementu TableAdapter do typu zestawu danych odpowiedni schemat dataTable jest określany przez główne zapytanie TableAdapter. Jeśli na przykład główne zapytanie zwraca pola danych A, B i C, tabela DataTable będzie zawierać trzy odpowiednie kolumny o nazwach A, B i C. Oprócz głównego zapytania tabelaAdapter może zawierać dodatkowe zapytania, które zwracają, być może, podzbiór danych na podstawie określonego parametru. Na przykład oprócz ProductsTableAdapter
głównego zapytania, które zwraca informacje o wszystkich produktach, zawiera również metody, takie jak GetProductsByCategoryID(categoryID)
i GetProductByProductID(productID)
, które zwracają określone informacje o produkcie na podstawie podanego parametru.
Model schematu tabeli DataTable odzwierciedla główne zapytanie TableAdapter działa dobrze, jeśli wszystkie metody TableAdapter zwracają te same lub mniej pól danych niż te określone w zapytaniu głównym. Jeśli metoda TableAdapter musi zwrócić dodatkowe pola danych, należy odpowiednio rozwinąć schemat tabeli danych DataTable. W temacie Master/Detail Using a Bulleted List of Master Records with a Details DataList tutorial (Szczegóły DataList) dodaliśmy metodę do CategoriesTableAdapter
zwracanych CategoryID
pól , CategoryName
i Description
danych zdefiniowanych w zapytaniu głównym oraz NumberOfProducts
, dodatkowe pole danych, które zgłosiło liczbę produktów skojarzonych z każdą kategorią. Ręcznie dodaliśmy nową kolumnę do CategoriesDataTable
obiektu w celu przechwycenia NumberOfProducts
wartości pola danych z tej nowej metody.
Zgodnie z opisem w samouczku Przekazywanie plików należy zadbać o to, aby elementy TableAdapters używały instrukcji AD-hoc SQL i miały metody, których pola danych nie są dokładnie zgodne z głównym zapytaniem. Jeśli kreator konfiguracji tableAdapter zostanie ponownie uruchomiony, zaktualizuje wszystkie metody tableAdapter tak, aby ich lista pól danych była zgodna z głównym zapytaniem. W związku z tym wszystkie metody z dostosowanymi listami kolumn zostaną przywrócone do głównej listy kolumn zapytania i nie zwracają oczekiwanych danych. Ten problem nie występuje podczas korzystania z procedur składowanych.
W tym samouczku przyjrzymy się sposobom rozszerzania schematu tabeli danych w celu uwzględnienia dodatkowych kolumn. Ze względu na kruchość instrukcji TableAdapter podczas korzystania z instrukcji AD-hoc SQL w tym samouczku będziemy używać procedur składowanych. Aby uzyskać więcej informacji na temat konfigurowania obiektu TableAdapters zestawu danych typowych, zapoznaj się z samouczkiem Tworzenie nowych procedur składowanych zestawu danych .
Krok 1. Dodawanie kolumnyPriceQuartile
do elementuProductsDataTable
W samouczku Tworzenie nowych procedur składowanych dla typowych zestawów danych TableAdapters utworzyliśmy typowy zestaw danych o nazwie NorthwindWithSprocs
. Ten zestaw danych zawiera obecnie dwie tabele danych: ProductsDataTable
i EmployeesDataTable
. Ma ProductsTableAdapter
następujące trzy metody:
GetProducts
— główne zapytanie, które zwraca wszystkie rekordy zProducts
tabeliGetProductsByCategoryID(categoryID)
— zwraca wszystkie produkty o określonym identyfikatorze categoryID.GetProductByProductID(productID)
— zwraca określony produkt o określonym identyfikatorze productID.
Główne zapytanie i dwie dodatkowe metody zwracają ten sam zestaw pól danych, a mianowicie wszystkie kolumny z Products
tabeli. Nie ma skorelowanych podquerii ani JOIN
ściągania powiązanych danych z Categories
tabel lub Suppliers
. W związku z tym kolumna ProductsDataTable
zawiera odpowiednią kolumnę dla każdego pola w Products
tabeli.
Na potrzeby tego samouczka dodajmy metodę do ProductsTableAdapter
nazwanej, GetProductsWithPriceQuartile
która zwraca wszystkie produkty. Oprócz standardowych pól GetProductsWithPriceQuartile
danych produktu będzie również zawierać PriceQuartile
pole danych, które wskazuje, w którym kwartylu spada cena produktu. Na przykład te produkty, których ceny są w najdroższych 25% będą miały PriceQuartile
wartość 1, podczas gdy te, których ceny spadną dolnej 25%, będą miały wartość 4. Zanim jednak zaczniemy martwić się o utworzenie procedury składowanej w celu zwrócenia tych informacji, najpierw musimy zaktualizować ProductsDataTable
element , aby uwzględnić kolumnę w celu przechowywania PriceQuartile
wyników podczas GetProductsWithPriceQuartile
używania metody.
Otwórz element NorthwindWithSprocs
DataSet i kliknij prawym przyciskiem myszy element ProductsDataTable
. Wybierz pozycję Dodaj z menu kontekstowego, a następnie wybierz pozycję Kolumna.
Rysunek 1. Dodawanie nowej kolumny do elementu ProductsDataTable
(kliknij, aby wyświetlić obraz pełnowymiarowy)
Spowoduje to dodanie nowej kolumny do tabeli danych o nazwie Column1 typu System.String
. Musimy zaktualizować nazwę tej kolumny na PriceQuartile i jej typ, ponieważ będzie ona używana do przechowywania liczby z zakresu od 1 do System.Int32
4. Wybierz nowo dodaną kolumnę w ProductsDataTable
obiekcie i z okno Właściwości ustaw Name
właściwość na PriceQuartile i DataType
właściwość na System.Int32
.
Rysunek 2. Ustawianie właściwości nowej kolumny Name
i DataType
(kliknij, aby wyświetlić obraz pełnowymiarowy)
Jak pokazano na rysunku 2, istnieją dodatkowe właściwości, które można ustawić, takie jak to, czy wartości w kolumnie muszą być unikatowe, jeśli kolumna jest kolumną automatycznego zwiększania, niezależnie od tego, czy wartości bazy danych NULL
są dozwolone itd. Pozostaw te wartości ustawione na wartości domyślne.
Krok 2. TworzenieGetProductsWithPriceQuartile
metody
Teraz, gdy element ProductsDataTable
został zaktualizowany w celu uwzględnienia PriceQuartile
kolumny, możemy przystąpić do tworzenia GetProductsWithPriceQuartile
metody. Zacznij od kliknięcia prawym przyciskiem myszy pozycji TableAdapter i wybrania pozycji Dodaj zapytanie z menu kontekstowego. Spowoduje to wyświetlenie kreatora konfiguracji zapytań TableAdapter, który najpierw monituje nas o to, czy chcemy użyć instrukcji AD-hoc SQL, czy nowej lub istniejącej procedury składowanej. Ponieważ nie mamy jeszcze procedury składowanej, która zwraca dane kwartylu cen, pozwólmy tableAdapter utworzyć dla nas tę procedurę składowaną. Wybierz opcję Utwórz nową procedurę składowaną i kliknij przycisk Dalej.
Rysunek 3. Poinstruuj Kreatora tableAdapter, aby utworzyć procedurę składowaną dla nas (kliknij, aby wyświetlić obraz pełnowymiarowy)
Na kolejnym ekranie pokazanym na rysunku 4 kreator pyta nas o typ zapytania do dodania. GetProductsWithPriceQuartile
Ponieważ metoda zwróci wszystkie kolumny i rekordy z Products
tabeli, wybierz opcję SELECT, która zwraca wiersze, a następnie kliknij przycisk Dalej.
Rysunek 4. Zapytanie będzie instrukcją zwracającą SELECT
wiele wierszy (kliknij, aby wyświetlić obraz pełnowymiarowy)
Następnie zostanie wyświetlony monit o SELECT
podanie zapytania. Wprowadź następujące zapytanie w kreatorze:
SELECT ProductID, ProductName, SupplierID, CategoryID,
QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder,
ReorderLevel, Discontinued,
NTILE(4) OVER (ORDER BY UnitPrice DESC) as PriceQuartile
FROM Products
Powyższe zapytanie używa nowej NTILE
funkcji SQL Server 2005, aby podzielić wyniki na cztery grupy, w których grupy są określane według UnitPrice
wartości posortowanych w kolejności malejącej.
Niestety konstruktor zapytań nie wie, jak przeanalizować OVER
słowo kluczowe i wyświetli błąd podczas analizowania powyższego zapytania. W związku z tym wprowadź powyższe zapytanie bezpośrednio w polu tekstowym w kreatorze bez użycia konstruktora zapytań.
Uwaga
Aby uzyskać więcej informacji na temat funkcji NTILE i SQL Server 2005 innych funkcji klasyfikacji, zobacz ROW_NUMBER (Transact-SQL) i sekcję Funkcje klasyfikacji z SQL Server 2005 Books Online.
Po wprowadzeniu zapytania i kliknięciu SELECT
przycisku Dalej kreator poprosi nas o podanie nazwy procedury składowanej, która zostanie utworzona. Nadaj nowej procedurze Products_SelectWithPriceQuartile
składowanej nazwę i kliknij przycisk Dalej.
Rysunek 5. Nadaj nazwę procedurze Products_SelectWithPriceQuartile
składowanej (kliknij, aby wyświetlić obraz pełnowymiarowy)
Na koniec zostanie wyświetlony monit o nadenie nazwy metod TableAdapter. Pozostaw zaznaczone pola wyboru Wypełnij tabelę danych i Zwracaj tabelę danych oraz nazwij metody FillWithPriceQuartile
i GetProductsWithPriceQuartile
.
Rysunek 6. Nadaj nazwę metod tableAdapter i kliknij przycisk Zakończ (kliknij, aby wyświetlić obraz pełnowymiarowy)
Po określeniu SELECT
zapytania oraz procedurze składowanej i metodach TableAdapter o nazwie kliknij przycisk Zakończ, aby ukończyć pracę kreatora. W tym momencie może zostać wyświetlone ostrzeżenie lub dwa z kreatora z informacją, że OVER
konstrukcja lub instrukcja SQL nie jest obsługiwana. Te ostrzeżenia można zignorować.
Po ukończeniu pracy kreatora narzędzie TableAdapter powinno zawierać FillWithPriceQuartile
metody i GetProductsWithPriceQuartile
, a baza danych powinna zawierać procedurę składowaną o nazwie Products_SelectWithPriceQuartile
. Poświęć chwilę, aby sprawdzić, czy tabela TableAdapter rzeczywiście zawiera tę nową metodę i że procedura składowana została poprawnie dodana do bazy danych. Jeśli podczas sprawdzania bazy danych nie widzisz procedury składowanej, spróbuj kliknąć prawym przyciskiem myszy folder Procedury składowane i wybrać polecenie Odśwież.
Rysunek 7. Sprawdź, czy nowa metoda została dodana do tabeli TableAdapter
Rysunek 8. Upewnij się, że baza danych zawiera procedurę Products_SelectWithPriceQuartile
składowaną (kliknij, aby wyświetlić obraz pełnowymiarowy)
Uwaga
Jedną z zalet korzystania z procedur składowanych zamiast instrukcji ad hoc SQL jest to, że ponowne uruchomienie kreatora konfiguracji TableAdapter nie spowoduje modyfikacji list kolumn procedur składowanych. Sprawdź to, klikając prawym przyciskiem myszy tabelę TableAdapter, wybierając opcję Konfiguruj z menu kontekstowego, aby uruchomić kreatora, a następnie klikając przycisk Zakończ, aby go ukończyć. Następnie przejdź do bazy danych i wyświetl procedurę Products_SelectWithPriceQuartile
składowaną. Należy pamiętać, że lista kolumn nie została zmodyfikowana. Gdyby używaliśmy instrukcji AD-hoc SQL, ponownie uruchomiono kreatora konfiguracji TableAdapter, przywróciłoby listę kolumn zapytania, aby dopasować listę kolumn zapytania do listy kolumn głównych zapytań, usuwając w ten sposób instrukcję NTILE z zapytania używanego przez metodę GetProductsWithPriceQuartile
.
Po wywołaniu metody warstwy GetProductsWithPriceQuartile
dostępu do danych metoda TableAdapter wykonuje Products_SelectWithPriceQuartile
procedurę składowaną i dodaje wiersz do ProductsDataTable
każdego zwróconego rekordu. Pola danych zwracane przez procedurę składowaną są mapowane na ProductsDataTable
kolumny. Ponieważ istnieje PriceQuartile
pole danych zwracane z procedury składowanej, jego wartość jest przypisywana do ProductsDataTable
kolumny s PriceQuartile
.
Dla tych metod TableAdapter, których zapytania nie zwracają PriceQuartile
pola danych, PriceQuartile
wartość kolumny jest wartością określoną przez jej DefaultValue
właściwość. Jak pokazano na rysunku 2, ta wartość jest ustawiona na DBNull
wartość , wartość domyślna. Jeśli wolisz inną wartość domyślną, po prostu ustaw DefaultValue
właściwość odpowiednio. Upewnij się, że DefaultValue
wartość jest prawidłowa, biorąc pod uwagę kolumny DataType
(tj System.Int32
. dla kolumny PriceQuartile
).
Na tym etapie wykonaliśmy kroki niezbędne do dodania dodatkowej kolumny do tabeli DataTable. Aby sprawdzić, czy ta dodatkowa kolumna działa zgodnie z oczekiwaniami, utwórzmy stronę ASP.NET, która wyświetla nazwę, cenę i kwartyl każdego produktu. Zanim to zrobimy, najpierw musimy zaktualizować warstwę logiki biznesowej, aby uwzględnić metodę, która wywołuje metodę dal w dół do metody DAL GetProductsWithPriceQuartile
. Następnie zaktualizujemy BLL w kroku 3, a następnie utworzymy stronę ASP.NET w kroku 4.
Krok 3. Rozszerzanie warstwy logiki biznesowej
Przed użyciem nowej GetProductsWithPriceQuartile
metody z warstwy prezentacji należy najpierw dodać odpowiednią metodę do BLL. ProductsBLLWithSprocs
Otwórz plik klasy i dodaj następujący kod:
[System.ComponentModel.DataObjectMethodAttribute
(System.ComponentModel.DataObjectMethodType.Select, false)]
public NorthwindWithSprocs.ProductsDataTable GetProductsWithPriceQuartile()
{
return Adapter.GetProductsWithPriceQuartile();
}
Podobnie jak inne metody pobierania danych w ProductsBLLWithSprocs
metodzie , GetProductsWithPriceQuartile
metoda po prostu wywołuje odpowiednią GetProductsWithPriceQuartile
metodę DAL i zwraca jej wyniki.
Krok 4. Wyświetlanie informacji kwartylu cen na stronie internetowej ASP.NET
Po zakończeniu dodawania BLL możemy utworzyć stronę ASP.NET, która pokazuje kwartyl cen dla każdego produktu. AddingColumns.aspx
Otwórz stronę w folderze AdvancedDAL
i przeciągnij kontrolkę GridView z przybornika do Projektant, ustawiając jej ID
właściwość na Products
. Z tagu inteligentnego GridView powiąż go z nowym obiektem ObjectDataSource o nazwie ProductsDataSource
. Skonfiguruj obiekt ObjectDataSource do używania ProductsBLLWithSprocs
metody s GetProductsWithPriceQuartile
klasy. Ponieważ będzie to siatka tylko do odczytu, ustaw listy rozwijane na kartach UPDATE, INSERT i DELETE na wartość (Brak).
Rysunek 9. Konfigurowanie obiektu ObjectDataSource do używania ProductsBLLWithSprocs
klasy (kliknij, aby wyświetlić obraz pełnowymiarowy)
Rysunek 10. Pobieranie informacji o produkcie GetProductsWithPriceQuartile
z metody (kliknij, aby wyświetlić obraz pełnowymiarowy)
Po ukończeniu pracy kreatora Konfigurowanie źródła danych program Visual Studio automatycznie doda pole BoundField lub CheckBoxField do kontrolki GridView dla każdego pola danych zwracanego przez metodę . Jedno z tych pól danych to PriceQuartile
, czyli kolumna dodana do ProductsDataTable
kroku 1.
Edytuj pola kontrolki GridView, usuwając wszystkie ProductName
pola , UnitPrice
i PriceQuartile
BoundFields. Skonfiguruj pole UnitPrice
BoundField, aby sformatować jego wartość jako walutę i odpowiednio UnitPrice
wyrównać do środka i PriceQuartile
pola BoundFields. Na koniec zaktualizuj pozostałe właściwości BoundFields HeaderText
odpowiednio do właściwości Product, Price i Price Quartile. Zaznacz również pole wyboru Włącz sortowanie z tagu inteligentnego GridView.
Po tych modyfikacjach znaczniki deklaratywne gridView i ObjectDataSource powinny wyglądać następująco:
<asp:GridView ID="Products" runat="server" AllowSorting="True"
AutoGenerateColumns="False" DataKeyNames="ProductID"
DataSourceID="ProductsDataSource">
<Columns>
<asp:BoundField DataField="ProductName" HeaderText="Product"
SortExpression="ProductName" />
<asp:BoundField DataField="UnitPrice" DataFormatString="{0:c}"
HeaderText="Price" HtmlEncode="False"
SortExpression="UnitPrice">
<ItemStyle HorizontalAlign="Right" />
</asp:BoundField>
<asp:BoundField DataField="PriceQuartile" HeaderText="Price Quartile"
SortExpression="PriceQuartile">
<ItemStyle HorizontalAlign="Center" />
</asp:BoundField>
</Columns>
</asp:GridView>
<asp:ObjectDataSource ID="ProductsDataSource" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetProductsWithPriceQuartile"
TypeName="ProductsBLLWithSprocs">
</asp:ObjectDataSource>
Rysunek 11 przedstawia tę stronę po odwiedzeniu za pośrednictwem przeglądarki. Należy pamiętać, że początkowo produkty są uporządkowane według ich ceny w kolejności malejącej, a każdy produkt ma przypisaną odpowiednią PriceQuartile
wartość. Oczywiście te dane można sortować według innych kryteriów z wartością kolumny kwartylu cen nadal odzwierciedlając klasyfikację produktu w odniesieniu do ceny (patrz Rysunek 12).
Rysunek 11. Produkty są uporządkowane według ich cen (kliknij, aby wyświetlić obraz pełnowymiarowy)
Rysunek 12. Produkty są uporządkowane według ich nazw (kliknij, aby wyświetlić obraz w pełnym rozmiarze)
Uwaga
Za pomocą kilku wierszy kodu możemy rozszerzyć obiekt GridView, tak aby wiersze produktów zostały kolorowe na podstawie ich PriceQuartile
wartości. Możemy kolorować te produkty w pierwszym kwartylu jasnozielony, te w drugim kwartylu jasnożółtym i tak dalej. Zachęcam do poświęć chwilę, aby dodać tę funkcjonalność. Jeśli potrzebujesz modułu odświeżania podczas formatowania kontrolki GridView, zapoznaj się z samouczkiem Custom Formatting Based Data (Formatowanie niestandardowe oparte na danych ).
Alternatywne podejście — tworzenie innego elementu TableAdapter
Jak pokazano w tym samouczku, podczas dodawania metody do kontrolki TableAdapter, która zwraca pola danych inne niż te zapisane przez zapytanie główne, możemy dodać odpowiednie kolumny do tabeli DataTable. Takie podejście sprawdza się jednak tylko wtedy, gdy w metodzie TableAdapter istnieje niewielka liczba metod, które zwracają różne pola danych i jeśli te alternatywne pola danych nie różnią się zbytnio od zapytania głównego.
Zamiast dodawać kolumny do tabeli DataTable, możesz zamiast tego dodać inny element TableAdapter do zestawu danych, który zawiera metody z pierwszego obiektu TableAdapter, który zwraca różne pola danych. W tym samouczku zamiast dodawać kolumnę PriceQuartile
do ProductsDataTable
obiektu (gdzie jest używana tylko przez GetProductsWithPriceQuartile
metodę), możemy dodać dodatkowy element TableAdapter do zestawu danych o nazwie ProductsWithPriceQuartileTableAdapter
, który użył Products_SelectWithPriceQuartile
procedury składowanej jako głównego zapytania. ASP.NET strony, które musiały uzyskać informacje o produkcie z kwartylem cen, będą używać ProductsWithPriceQuartileTableAdapter
wartości , a te, które nie mogły nadal korzystać z elementu ProductsTableAdapter
.
Dodając nowy element TableAdapter, tabele DataTable pozostają niezmienione, a ich kolumny dokładnie odzwierciedlają pola danych zwracane przez metody tableAdapter. Jednak dodatkowe elementy TableAdapters mogą wprowadzać powtarzające się zadania i funkcje. Jeśli na przykład te strony ASP.NET, które wyświetlały kolumnę PriceQuartile
, również potrzebne do zapewnienia obsługi wstawiania, aktualizowania i usuwania, ProductsWithPriceQuartileTableAdapter
muszą mieć odpowiednio InsertCommand
skonfigurowane właściwości , UpdateCommand
i DeleteCommand
. Chociaż te właściwości dublowałyby ProductsTableAdapter
s, ta konfiguracja wprowadza dodatkowy krok. Ponadto istnieją dwa sposoby aktualizowania, usuwania lub dodawania produktu do bazy danych — za pomocą ProductsTableAdapter
klas i ProductsWithPriceQuartileTableAdapter
.
Pobieranie dla tego samouczka zawiera klasę ProductsWithPriceQuartileTableAdapter
w zestawie NorthwindWithSprocs
danych, która ilustruje to alternatywne podejście.
Podsumowanie
W większości scenariuszy wszystkie metody w metodzie TableAdapter zwracają ten sam zestaw pól danych, ale istnieją sytuacje, w których określona metoda lub dwie mogą wymagać zwrócenia dodatkowego pola. Na przykład w samouczku Master/Detail Using a Bulleted List of Master Records with a Details DataList (Lista punktowana rekordów głównych z listą szczegółów dataList ) dodaliśmy metodę , CategoriesTableAdapter
która oprócz pól danych zapytania głównego zwróciła NumberOfProducts
pole, które zgłosiło liczbę produktów skojarzonych z każdą kategorią. W tym samouczku przyjrzeliśmy się dodawaniu metody w ProductsTableAdapter
pole, które zwróciło PriceQuartile
pole oprócz pól danych zapytania głównego. Aby przechwytywać dodatkowe pola danych zwracane przez metody tableAdapter, musimy dodać odpowiednie kolumny do tabeli DataTable.
Jeśli planujesz ręczne dodawanie kolumn do tabeli DataTable, zaleca się użycie procedur składowanych przez obiekt TableAdapter. Jeśli tableAdapter używa ad hoc instrukcji SQL, za każdym razem, gdy kreator konfiguracji tableAdapter zostanie uruchomiony wszystkie listy pól danych metod, zostaną przywrócone do pól danych zwracanych przez zapytanie główne. Ten problem nie obejmuje procedur składowanych, dlatego są one zalecane i były używane w tym samouczku.
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 Randy Schmidt, Jacky Goor, Bernadette Leigh i Hilton Giesenow. Chcesz przejrzeć nadchodzące artykuły MSDN? Jeśli tak, upuść mi wiersz pod adresemmitchell@4GuysFromRolla.com .