Přidání dalších sloupců do tabulky DataTable (VB)
Při použití Průvodce objektem TableAdapter k vytvoření typové datové sady obsahuje odpovídající tabulka DataTable sloupce vrácené hlavním databázovým dotazem. Existují ale situace, kdy datatable musí obsahovat další sloupce. V tomto kurzu se dozvíme, proč se doporučují uložené procedury, když potřebujeme další sloupce DataTable.
Úvod
Při přidávání objektu TableAdapter do typed DataSet je odpovídající schéma DataTable s určeno hlavním dotazem Objektu tableadapter. Pokud například hlavní dotaz vrátí datová pole A, B a C, bude mít tabulka DataTable tři odpovídající sloupce s názvy A, B a C. Kromě svého hlavního dotazu může Objekt TableAdapter obsahovat další dotazy, které vrací, například, podmnožinu dat na základě nějakého parametru. Kromě hlavního ProductsTableAdapter
dotazu, který vrací informace o všech produktech, obsahuje například také metody jako GetProductsByCategoryID(categoryID)
a GetProductByProductID(productID)
, které vrací konkrétní informace o produktu na základě zadaného parametru.
Model schématu DataTable s odráží hlavní dotaz TableAdapter s funguje dobře, pokud všechny metody TableAdapter s vrací stejná nebo méně datových polí než ty zadané v hlavním dotazu. Pokud metoda TableAdapter potřebuje vracet další datová pole, měli bychom odpovídajícím způsobem rozbalit schéma DataTable s. V kurzu Master/Detail Using a Bulleted List of Master Records with a Details DataList jsme přidali metodu, CategoriesTableAdapter
která vrátila CategoryID
datová pole , CategoryName
a Description
definovaná v hlavním dotazu plus NumberOfProducts
další datové pole, které nahlásilo počet produktů přidružených k jednotlivým kategoriím. Ručně jsme do CategoriesDataTable
pole přidali nový sloupec, aby bylo možné zachytit hodnotu datového NumberOfProducts
pole z této nové metody.
Jak je popsáno v kurzu Nahrávání souborů , u objektů TableAdapter, které používají ad hoc příkazy SQL a mají metody, jejichž datová pole přesně neodpovídají hlavnímu dotazu, je potřeba věnovat velkou pozornost. Pokud se znovu spustí Průvodce konfigurací objektu TableAdapter, aktualizuje všechny metody TableAdapter tak, aby seznam jejich datových polí odpovídal hlavnímu dotazu. V důsledku toho se všechny metody s přizpůsobenými seznamy sloupců vrátí do seznamu sloupců hlavního dotazu a nevrátí očekávaná data. K tomuto problému nedochází při použití uložených procedur.
V tomto kurzu se podíváme na to, jak rozšířit schéma DataTable o další sloupce. Vzhledem k křehkosti objektu TableAdapter při použití ad hoc příkazů SQL použijeme v tomto kurzu uložené procedury. Další informace o konfiguraci objektu TableAdapter pro použití uložených procedur najdete v kurzech Vytváření nových uložených procedur pro objekty TableAdapter typed DataSet a Using Existing Stored Procedures (Použití existujících uložených procedur) v kurzech Typed DataSet s TableAdapter .
Krok 1: PřidáníPriceQuartile
sloupce doProductsDataTable
V kurzu Vytváření nových uložených procedur pro Typed DataSet s TableAdapter jsme vytvořili typovou sadu dat s názvem NorthwindWithSprocs
. Tato datová sada v současné době obsahuje dvě tabulky data: ProductsDataTable
a EmployeesDataTable
. Má ProductsTableAdapter
následující tři metody:
GetProducts
– hlavní dotaz, který vrací všechny záznamy z tabulky.Products
GetProductsByCategoryID(categoryID)
– vrátí všechny produkty se zadaným ID kategorie.GetProductByProductID(productID)
- vrátí konkrétní produkt se zadaným ID produktu.
Hlavní dotaz a dvě další metody vrátí stejnou sadu datových polí, konkrétně všechny sloupce z Products
tabulky. Neexistují žádné korelované poddotazy nebo JOIN
s, které by načítá související data z Categories
tabulek nebo Suppliers
. ProductsDataTable
Proto má odpovídající sloupec pro každé pole v tabulceProducts
.
Pro účely tohoto kurzu přidáme do ProductsTableAdapter
pojmenované GetProductsWithPriceQuartile
metody metodu, která vrátí všechny produkty. Kromě standardních datových polí produktu bude obsahovat PriceQuartile
také datové pole, které označuje, GetProductsWithPriceQuartile
pod který kvartil spadá cena produktu. Například produkty, jejichž ceny jsou v nejdražších 25 %, budou mít PriceQuartile
hodnotu 1, zatímco produkty, jejichž ceny spadají do nejnižších 25 %, budou mít hodnotu 4. Než se však začneme starat o vytvoření uložené procedury pro vrácení těchto informací, musíme nejprve aktualizovat ProductsDataTable
sloupec, který bude obsahovat PriceQuartile
výsledky při GetProductsWithPriceQuartile
použití metody.
Otevřete datovou NorthwindWithSprocs
sadu a klikněte pravým tlačítkem na .ProductsDataTable
V místní nabídce zvolte Přidat a pak vyberte Sloupec.
Obrázek 1: Přidání nového sloupce do ProductsDataTable
(kliknutím zobrazíte obrázek v plné velikosti)
Tím se do tabulky DataTable přidá nový sloupec s názvem Column1 typu System.String
. Musíme aktualizovat název tohoto sloupce na PriceQuartile a jeho typ na, System.Int32
protože se použije k uložení čísla mezi 1 a 4. Vyberte nově přidaný sloupec v ProductsDataTable
a v okno Vlastnosti nastavte Name
vlastnost PriceQuartile a DataType
vlastnost na System.Int32
hodnotu .
Obrázek 2: Nastavení vlastností a DataType
nových sloupců Name
(kliknutím zobrazíte obrázek v plné velikosti)
Jak ukazuje obrázek 2, je možné nastavit další vlastnosti, například to, jestli hodnoty ve sloupci musí být jedinečné, jestli je sloupec sloupcem s automatickým přírůstkem, jestli jsou povolené hodnoty databáze NULL
atd. Ponechte tyto hodnoty nastavené na výchozí hodnoty.
Krok 2: VytvořeníGetProductsWithPriceQuartile
metody
Teď, když ProductsDataTable
jsme aktualizovali PriceQuartile
sloupec, jsme připraveni vytvořit metodu GetProductsWithPriceQuartile
. Začněte tak, že kliknete pravým tlačítkem na objekt TableAdapter a v místní nabídce zvolíte Přidat dotaz. Tím se zobrazí průvodce konfigurace dotazů tableadapter, který nás nejprve vyzve k tomu, jestli chceme použít ad hoc příkazy SQL nebo novou nebo existující uloženou proceduru. Vzhledem k tomu, že ještě nemáme uloženou proceduru, která vrací kvartilová data o cenách, povolme tabulkovémuada vytvořit tuto uloženou proceduru pro nás. Vyberte možnost Vytvořit novou uloženou proceduru a klikněte na Další.
Obrázek 3: Požádejte průvodce TableAdapter, aby vytvořil uloženou proceduru (kliknutím zobrazíte obrázek v plné velikosti)
Na následující obrazovce, která je znázorněna na obrázku 4, se průvodce zeptá, jaký typ dotazu přidat. Vzhledem k tomu, že GetProductsWithPriceQuartile
metoda vrátí všechny sloupce a záznamy z Products
tabulky, vyberte možnost VYBRAT, která vrací řádky a klikněte na Další.
Obrázek 4: Náš dotaz bude příkazem SELECT
, který vrátí více řádků (kliknutím zobrazíte obrázek v plné velikosti).
Dále se zobrazí výzva k SELECT
zadání dotazu. Do průvodce zadejte následující dotaz:
SELECT ProductID, ProductName, SupplierID, CategoryID,
QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder,
ReorderLevel, Discontinued,
NTILE(4) OVER (ORDER BY UnitPrice DESC) as PriceQuartile
FROM Products
Výše uvedený dotaz používá novou NTILE
funkci SQL Server 2005 k rozdělení výsledků do čtyř skupin, kde jsou skupiny určeny UnitPrice
hodnotami seřazenými v sestupném pořadí.
Tvůrce dotazů bohužel neví, jak analyzovat OVER
klíčové slovo, a při analýze výše uvedeného dotazu zobrazí chybu. Proto zadejte výše uvedený dotaz přímo do textového pole průvodce bez použití Tvůrce dotazů.
Poznámka
Další informace o funkcích řazení ntile a SQL Server 2005 s najdete v tématu ROW_NUMBER (Transact-SQL) a v části Funkce řazení z SQL Server 2005 Books Online.
Po zadání SELECT
dotazu a kliknutí na Další nás průvodce požádá o zadání názvu uložené procedury, která se vytvoří. Pojmenujte novou uloženou proceduru Products_SelectWithPriceQuartile
a klikněte na Další.
Obrázek 5: Pojmenujte uloženou proceduru Products_SelectWithPriceQuartile
(kliknutím zobrazíte obrázek v plné velikosti)
Nakonec jsme vyzváni k pojmenování metod TableAdapter. Ponechte zaškrtnutá políčka Vyplnit tabulku DataTable a Vrátit dataTable a pojmenujte metody FillWithPriceQuartile
a GetProductsWithPriceQuartile
.
Obrázek 6: Pojmenujte metody TableAdapter s a klikněte na Dokončit (kliknutím zobrazíte obrázek v plné velikosti)
Se zadaným SELECT
dotazem a pojmenovanou uloženou procedurou a metodami TableAdapter klikněte na Dokončit a dokončete průvodce. V tomto okamžiku se může zobrazit upozornění nebo dvě z průvodce oznamující, že konstruktor OVER
nebo příkaz SQL není podporován. Tato upozornění je možné ignorovat.
Po dokončení průvodce by objekt TableAdapter měl obsahovat FillWithPriceQuartile
metody a GetProductsWithPriceQuartile
a databáze by měla obsahovat uloženou proceduru s názvem Products_SelectWithPriceQuartile
. Chvíli si ověřte, že Objekt TableAdapter skutečně obsahuje tuto novou metodu a že uložená procedura byla správně přidána do databáze. Pokud při kontrole databáze nevidíte uloženou proceduru, zkuste kliknout pravým tlačítkem na složku Uložené procedury a zvolit Aktualizovat.
Obrázek 7: Ověření přidání nové metody do třídy TableAdapter
Obrázek 8: Ujistěte se, že databáze obsahuje uloženou proceduru Products_SelectWithPriceQuartile
(kliknutím zobrazíte obrázek v plné velikosti)
Poznámka
Jednou z výhod použití uložených procedur místo ad hoc příkazů SQL je, že opětovné spuštění Průvodce konfigurací objektu TableAdapter neupravuje seznamy sloupců uložených procedur. Ověřte to tak, že kliknete pravým tlačítkem myši na objekt TableAdapter, v místní nabídce zvolíte možnost Konfigurovat, aby se průvodce spustil, a kliknutím na Dokončit ho dokončete. Pak přejděte do databáze a prohlédněte si uloženou proceduru Products_SelectWithPriceQuartile
. Všimněte si, že jeho seznam sloupců nebyl změněn. Kdybychom používali ad hoc příkazy SQL, opětovné spuštění Průvodce konfigurací objektu TableAdapter by vrátilo tento seznam sloupců dotazu tak, aby odpovídal seznamu sloupců hlavního dotazu, a tím by se příkaz NTILE odebral z dotazu používaného GetProductsWithPriceQuartile
metodou.
Při vyvolání metody Data Access Layer s GetProductsWithPriceQuartile
tableAdapter spustí uloženou proceduru Products_SelectWithPriceQuartile
a přidá řádek do každého vráceného záznamu ProductsDataTable
. Datová pole vrácená uloženou procedurou se mapují na ProductsDataTable
sloupce s. Vzhledem k tomu, PriceQuartile
že se z uložené procedury vrací datové pole, je jeho hodnota přiřazena sloupci ProductsDataTable
s PriceQuartile
.
U metod TableAdapter, jejichž dotazy nevrací PriceQuartile
datové pole, PriceQuartile
je hodnota sloupce s hodnota určená jeho DefaultValue
vlastností. Jak ukazuje obrázek 2, je tato hodnota nastavená na DBNull
výchozí hodnotu. Pokud dáváte přednost jiné výchozí hodnotě, jednoduše nastavte DefaultValue
vlastnost odpovídajícím způsobem. Stačí se ujistit, že DefaultValue
hodnota je platná vzhledem k sloupcům DataType
(tj. System.Int32
pro PriceQuartile
sloupec).
V tomto okamžiku jsme provedli nezbytné kroky pro přidání dalšího sloupce do tabulky DataTable. Pokud chcete ověřit, že tento další sloupec funguje podle očekávání, pojďme vytvořit stránku ASP.NET, která zobrazuje názvy, ceny a ceny jednotlivých produktů. Než to ale uděláme, musíme nejprve aktualizovat vrstvu obchodní logiky tak, aby zahrnovala metodu, která volá metodu DAL GetProductsWithPriceQuartile
s. V kroku 3 aktualizujeme BLL a pak vytvoříme ASP.NET stránku v kroku 4.
Krok 3: Rozšíření vrstvy obchodní logiky
Než použijeme novou GetProductsWithPriceQuartile
metodu z prezentační vrstvy, měli bychom nejprve přidat odpovídající metodu do BLL. ProductsBLLWithSprocs
Otevřete soubor třídy a přidejte následující kód:
<System.ComponentModel.DataObjectMethodAttribute_
(System.ComponentModel.DataObjectMethodType.Select, False)> _
Public Function GetProductsWithPriceQuartile() As NorthwindWithSprocs.ProductsDataTable
Return Adapter.GetProductsWithPriceQuartile()
End Function
Stejně jako ostatní metody načítání dat v ProductsBLLWithSprocs
GetProductsWithPriceQuartile
systému metoda jednoduše zavolá odpovídající GetProductsWithPriceQuartile
metodu DAL a vrátí její výsledky.
Krok 4: Zobrazení informací o ceně kvartilu na webové stránce ASP.NET
Po dokončení přidání BLL jsme připraveni vytvořit ASP.NET stránku, která zobrazuje cenu kvartilu pro každý produkt. AddingColumns.aspx
Otevřete stránku ve AdvancedDAL
složce a přetáhněte Objekt GridView z panelu nástrojů do Designer nastavením jeho ID
vlastnosti na Products
. Z inteligentní značky GridView ji vytvořte vazbu na nový ObjectDataSource s názvem ProductsDataSource
. Nakonfigurujte ObjectDataSource tak, aby používal metodu ProductsBLLWithSprocs
třídy s GetProductsWithPriceQuartile
. Vzhledem k tomu, že se bude jednat o mřížku jen pro čtení, nastavte rozevírací seznamy na kartách UPDATE, INSERT a DELETE na (Žádné) .
Obrázek 9: Konfigurace objektu ObjectDataSource pro použití ProductsBLLWithSprocs
třídy (kliknutím zobrazíte obrázek v plné velikosti)
Obrázek 10: Načtení informací o produktu z GetProductsWithPriceQuartile
metody (kliknutím zobrazíte obrázek v plné velikosti)
Po dokončení průvodce Konfigurovat zdroj dat sada Visual Studio automaticky přidá BoundField nebo CheckBoxField do objektu GridView pro každé z datových polí vrácených metodou . Jedním z těchto datových polí je PriceQuartile
, což je sloupec, který jsme přidali do ProductsDataTable
pole v kroku 1.
Upravte pole GridView a odeberte všechna ProductName
pole kromě , UnitPrice
a PriceQuartile
BoundFields. UnitPrice
Nakonfigurujte BoundField tak, aby se jeho hodnota formátovala jako měna a aby byly UnitPrice
PriceQuartile
hodnoty BoundField zarovnané doprava a na střed. Nakonec aktualizujte zbývající vlastnosti BoundFields HeaderText
na Product( Produkt), Price (Cena) a Price Quartil (Cena kvartil). Zaškrtněte také políčko Enable Sorting (Povolit řazení) z inteligentní značky GridView.
Po těchto úpravách by deklarativní značky GridView a ObjectDataSource měly vypadat takto:
<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>
Obrázek 11 ukazuje tuto stránku při návštěvě prostřednictvím prohlížeče. Všimněte si, že na začátku jsou produkty seřazené podle ceny v sestupném pořadí, přičemž každému produktu je přiřazena odpovídající PriceQuartile
hodnota. Tato data se samozřejmě dají řadit podle jiných kritérií, přičemž hodnota sloupce Price Quartil (Cena kvartil) stále odráží pořadí produktů s ohledem na cenu (viz Obrázek 12).
Obrázek 11: Produkty jsou objednány podle jejich cen (kliknutím zobrazíte obrázek v plné velikosti)
Obrázek 12: Produkty jsou seřazené podle jejich názvů (kliknutím zobrazíte obrázek v plné velikosti)
Poznámka
Pomocí několika řádků kódu bychom mohli rozšířit GridView tak, aby zbarvil řádky produktu na základě jejich PriceQuartile
hodnoty. Můžeme tyto výrobky v prvním kvartilu obarvit světle zeleně, v druhém kvartilu světle žlutou a tak dále. Doporučujeme, abyste si na chvíli tuto funkci přidali. Pokud potřebujete opakovat formátování objektu GridView, projděte si kurz Vlastní formátování založené na datech .
Alternativní přístup – Vytvoření dalšího objektu TableAdapter
Jak jsme viděli v tomto kurzu, při přidávání metody do objektu TableAdapter, která vrací jiná datová pole než ta, která jsou napsaná hlavním dotazem, můžeme do tabulky DataTable přidat odpovídající sloupce. Takový přístup však funguje dobře pouze v případě, že v objektu TableAdapter existuje malý počet metod, které vrací různá datová pole, a pokud se tato alternativní datová pole příliš neliší od hlavního dotazu.
Místo přidávání sloupců do DataTable můžete místo toho přidat další objekt TableAdapter do datové sady, který obsahuje metody z prvního objektu TableAdapter, které vracejí různá datová pole. Pro účely tohoto kurzu jsme místo přidání PriceQuartile
sloupce do objektu ProductsDataTable
(kde ho GetProductsWithPriceQuartile
používá pouze metoda), mohli jsme do datové sady ProductsWithPriceQuartileTableAdapter
přidat další objekt TableAdapter, který jako hlavní dotaz použil uloženou Products_SelectWithPriceQuartile
proceduru. ASP.NET stránky, které potřebovaly získat informace o produktu s cenovým kvartilem ProductsWithPriceQuartileTableAdapter
, by používaly , zatímco stránky, které nebyly, mohly dál používat ProductsTableAdapter
.
Přidáním nového objektu TableAdapter zůstanou tabulky DataTables nepřipravené a jejich sloupce přesně zrcadlí datová pole vrácená jejich metodami TableAdapter. Další doplňky TableAdapter ale můžou zavádět opakující se úlohy a funkce. Pokud například tyto ASP.NET stránky, které zobrazovaly PriceQuartile
sloupec, potřebovaly také podporu vložení, aktualizace a odstranění, ProductsWithPriceQuartileTableAdapter
musí mít objekt správně nakonfigurované vlastnosti InsertCommand
, UpdateCommand
a DeleteCommand
. I když by tyto vlastnosti zrcadlily ProductsTableAdapter
s, tato konfigurace zavádí další krok. Kromě toho teď existují dva způsoby, jak aktualizovat, odstranit nebo přidat produkt do databáze – prostřednictvím ProductsTableAdapter
tříd a ProductsWithPriceQuartileTableAdapter
.
Soubor ke stažení pro tento kurz obsahuje ProductsWithPriceQuartileTableAdapter
třídu v NorthwindWithSprocs
datové sadě, která tento alternativní přístup ilustruje.
Souhrn
Ve většině scénářů vrátí všechny metody v objektu TableAdapter stejnou sadu datových polí, ale existují situace, kdy konkrétní metoda nebo dvě mohou potřebovat vrátit další pole. Například v kurzu Master/Detail Using a Bulleted List of Master Records with a Details DataList jsme přidali metodu , která kromě datových polí hlavního dotazu vrátila NumberOfProducts
pole, které hlásilo počet produktů přidružených k CategoriesTableAdapter
jednotlivým kategoriím. V tomto kurzu jsme se podívali na přidání metody, ProductsTableAdapter
která vrátila PriceQuartile
pole kromě datových polí hlavního dotazu. Pokud chcete zachytit další datová pole vrácená metodami TableAdapter, musíme do tabulky DataTable přidat odpovídající sloupce.
Pokud plánujete ručně přidávat sloupce do tabulky DataTable, doporučujeme, aby metoda TableAdapter používala uložené procedury. Pokud objekt TableAdapter používá ad hoc příkazy SQL, při každém spuštění průvodce konfigurací objektu TableAdapter se všechny seznamy datových polí metod vrátí k datovým polím vráceným hlavním dotazem. Tento problém se nevztahuje na uložené procedury, a proto se doporučují a v tomto kurzu se používaly.
Všechno nejlepší na programování!
O autorovi
Scott Mitchell, autor sedmi knih o ASP/ASP.NET a zakladatel 4GuysFromRolla.com, pracuje s webovými technologiemi Microsoftu od roku 1998. Scott pracuje jako nezávislý konzultant, školitel a spisovatel. Jeho nejnovější kniha je Sams Teach Yourself ASP.NET 2.0 in 24 Hours. Můžete ho zastihnout na mitchell@4GuysFromRolla.comadrese . nebo prostřednictvím jeho blogu, který najdete na adrese http://ScottOnWriting.NET.
Zvláštní poděkování
Tato série kurzů byla zkontrolována mnoha užitečnými recenzenty. Hlavními recenzenty pro tento kurz byli Randy Schmidt, Jacky Goor, Bernadette Leigh a Hilton Giesenow. Chtěli byste si projít své nadcházející články na webu MSDN? Pokud ano, dejte mi řádek na mitchell@4GuysFromRolla.com.