Sdílet prostřednictvím


Přidání dalších sloupců do tabulky DataTable (C#)

Scott Mitchell

Stáhnout PDF

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 zjistí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 určena hlavním dotazem objektu TableAdapter. Pokud například hlavní dotaz vrátí datová pole A, B a C, bude mít 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í 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é vracejí informace o konkrétním produktu na základě zadaného parametru.

Model schématu DataTable s odráží hlavní dotaz TableAdapter funguje dobře, pokud všechny metody TableAdapter vrací stejná nebo méně datových polí než ta, která jsou zadána v hlavním dotazu. Pokud metoda TableAdapter potřebuje vrátit další datová pole, měli bychom odpovídajícím způsobem rozšířit schéma DataTable. V kurzu Master/Detail Using a Bulleted List of Master Records with a Details DataList jsme přidali metodu , která vrátila CategoryIDdatová pole , CategoryNamea Description definovaná v hlavním dotazu plus NumberOfProductsdalší datové pole, které hlásilo počet produktů přidružených k CategoriesTableAdapter jednotlivým kategoriím. Ručně jsme do CategoriesDataTable třídy přidali nový sloupec, abychom z této nové metody zachytili hodnotu datového NumberOfProducts pole.

Jak je popsáno v kurzu Nahrávání souborů , je třeba věnovat velkou pozornost objektům TableAdapter, které používají ad hoc příkazy SQL a mají metody, jejichž datová pole přesně neodpovídají hlavnímu dotazu. Pokud je znovu spuštěn Průvodce konfigurací objektu TableAdapter, aktualizuje všechny metody TableAdapter tak, aby jejich seznam 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í k 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 tak, aby zahrnovalo další sloupce. Vzhledem k křehkosti objektu TableAdapter při použití ad hoc příkazů SQL budeme v tomto kurzu používat uložené procedury. Další informace o konfiguraci objektu TableAdapter pro použití uložených procedur najdete v kurzu Vytváření nových uložených procedur pro typed DataSet s Objekty TableAdapter .

Krok 1: PřidáníPriceQuartilesloupce doProductsDataTable

V kurzu Vytváření nových uložených procedur pro objekty TableAdapter typed DataSet jsme vytvořili typovou sadu dat s názvem NorthwindWithSprocs. Tato datová sada aktuálně obsahuje dvě tabulky DataTable: ProductsDataTable a EmployeesDataTable. Má ProductsTableAdapter následující tři metody:

  • GetProducts – hlavní dotaz, který vrací všechny záznamy z Products tabulky
  • 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 ani JOIN dotazy, které by přetahovaly 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 metodu s názvem GetProductsWithPriceQuartile , ProductsTableAdapter která vrátí všechny produkty. Kromě standardních datových polí produktu bude obsahovat PriceQuartile také datové pole, GetProductsWithPriceQuartile které určuje, pod který kvartil cena produktu spadá. 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 tak, aby zahrnoval sloupec pro uložení PriceQuartile výsledků 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.

Přidání nového sloupce do tabulky ProductsDataTable

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 na PriceQuartile a DataType vlastnost na System.Int32.

Nastavení vlastností New Column s Name (Název nového sloupce) a DataType (Typ dat)

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 jestli hodnoty ve sloupci musí být jedinečné, jestli je sloupec automatickým přírůstkem, jestli jsou povolené hodnoty databáze NULL atd. Tyto hodnoty nechte nastavené na výchozí hodnoty.

Krok 2: VytvořeníGetProductsWithPriceQuartilemetody

Teď, když jsme aktualizovali ProductsDataTablePriceQuartile 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 dotazu 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í data o cenách kvartilu, umožníme, aby pro nás TableAdapter vytvořil tuto uloženou proceduru. Vyberte možnost Vytvořit novou uloženou proceduru a klikněte na Další.

Požádejte průvodce TableAdapter, aby vytvořil uloženou proceduru pro nás.

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, znázorněné 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ší.

Náš dotaz bude příkaz SELECT, který vrátí více řádků.

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 zadání SELECT 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 hodnotami UnitPrice seřazenými sestupně.

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 v průvodci bez použití Tvůrce dotazů.

Poznámka

Další informace o ntile a SQL Server 2005 s další funkce řazení naleznete v části ROW_NUMBER (Transact-SQL) a Ranking Functions 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ší.

Pojmenujte uloženou proceduru Products_SelectWithPriceQuartile

Obrázek 5: Pojmenování uložené procedury Products_SelectWithPriceQuartile (kliknutím zobrazíte obrázek v plné velikosti)

Nakonec jsme vyzváni k pojmenování metod TableAdapter. Nechte zaškrtnutá políčka Fill a DataTable i Return a DataTable a pojmenujte metody FillWithPriceQuartile a GetProductsWithPriceQuartile.

Pojmenujte metody TableAdapter s a klikněte na Dokončit.

Obrázek 6: Pojmenujte metody TableAdapter 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 dokončete průvodce kliknutím na Dokončit. V tomto okamžiku se může od průvodce zobrazit upozornění, že konstruktor OVER nebo příkaz SQL není podporován. Tato upozornění lze 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 se ujistě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.

Ověřte, že byla do třídy TableAdapter přidána nová metoda.

Obrázek 7: Ověření přidání nové metody do třídy TableAdapter

Ujistěte se, že databáze obsahuje Products_SelectWithPriceQuartile uloženou proceduru.

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 příkazů SQL ad hoc je to, že opětovné spuštění průvodce konfigurací objektu TableAdapter nezmění seznamy sloupců uložených procedur. Ověřte to tak, že kliknete pravým tlačítkem na objekt TableAdapter, v místní nabídce zvolíte možnost Konfigurovat, aby se spustil průvodce, 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 příkazy SQL ad hoc, opětovné spuštění průvodce konfigurací tableadapter by vrátilo seznam sloupců dotazu tak, aby odpovídal hlavnímu seznamu sloupců 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 GetProductsWithPriceQuartile tableAdapter spustí uloženou proceduru Products_SelectWithPriceQuartile a přidá řádek do ProductsDataTable třídy pro každý vrácený záznam. Datová pole vrácená uloženou procedurou se mapují na ProductsDataTable sloupce s. Vzhledem k tomu, PriceQuartile že se z uložené procedury vrátí datové pole, přiřadí se jeho hodnota sloupci ProductsDataTable s PriceQuartile .

Pro metody TableAdapter, jejichž dotazy nevrací PriceQuartile datové pole, PriceQuartile je hodnota sloupce s hodnota určená jeho DefaultValue vlastností. Jak je znázorněno na obrázku 2, je tato hodnota nastavená na DBNullvýchozí hodnotu. Pokud dáváte přednost jiné výchozí hodnotě, jednoduše nastavte DefaultValue vlastnost odpovídajícím způsobem. Jen se ujistěte, že DefaultValue je hodnota platná vzhledem ke sloupci 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 NorthwindWithSprocs.ProductsDataTable GetProductsWithPriceQuartile()
{
    return Adapter.GetProductsWithPriceQuartile();
}

Stejně jako ostatní metody načítání dat v ProductsBLLWithSprocsGetProductsWithPriceQuartile 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é) .

Konfigurace objektu ObjectDataSource pro použití třídy ProductsBLLWithSprocs

Obrázek 9: Konfigurace objektu ObjectDataSource pro použití ProductsBLLWithSprocs třídy (kliknutím zobrazíte obrázek v plné velikosti)

Načtení informací o produktu z metody GetProductsWithPriceQuartile

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 ProductNamepole kromě , UnitPricea PriceQuartile BoundFields. UnitPrice Nakonfigurujte BoundField tak, aby se jeho hodnota formátovala jako měna a aby byly UnitPricePriceQuartile 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).

Produkty jsou objednány podle jejich cen

Obrázek 11: Produkty jsou objednány podle jejich cen (kliknutím zobrazíte obrázek v plné velikosti)

Produkty jsou seřazeny podle jejich názvů.

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, UpdateCommanda 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.