Vytvoření nových uložených procedur prvků TableAdapter typových sad dat (VB)
V předchozích kurzech jsme v našem kódu vytvořili příkazy SQL a předali příkazy do databáze, která se má spustit. Alternativním přístupem je použití uložených procedur, kde jsou příkazy SQL předdefinované v databázi. V tomto kurzu se dozvíte, jak pro nás Průvodce objektem TableAdapter vygenerovat nové uložené procedury.
Úvod
Vrstva přístupu k datům (DAL) pro tyto kurzy používá typové datové sady. Jak je popsáno v kurzu Vytvoření vrstvy přístupu k datům , typové datové sady se skládají z datových tabulek se silnými typy a objektů TableAdapter. DataTables představují logické entity v systému, zatímco Objekty TableAdapter jsou v rozhraní s podkladovou databází, aby prováděly práci s přístupem k datům. To zahrnuje naplnění tabulek DataTables daty, spouštění dotazů, které vrací skalární data, a vkládání, aktualizaci a odstraňování záznamů z databáze.
Příkazy SQL spouštěné pomocí objektů TableAdapter můžou být buď příkazy SQL ad hoc, jako SELECT columnList FROM TableName
je , nebo uložené procedury. TableAdaptery v naší architektuře používají ad hoc příkazy SQL. Mnoho vývojářů a správců databází ale kvůli zabezpečení, údržbě a aktualizovatelnosti dává přednost uloženým procedurám před ad hoc příkazy SQL. Jiní vřele preferují ad hoc příkazy SQL kvůli své flexibilitě. Ve své vlastní práci dávám přednost uloženým procedurám před ad hoc příkazy SQL, ale rozhodl jsem se použít ad hoc příkazy SQL, aby se zjednodušily dřívější kurzy.
Při definování objektu TableAdapter nebo přidávání nových metod průvodce TableAdapter s usnadňuje vytváření nových uložených procedur nebo používání existujících uložených procedur stejně jako použití ad hoc příkazů SQL. V tomto kurzu se podíváme, jak automaticky vygenerovat uložené procedury pomocí průvodce TableAdapter. V dalším kurzu se podíváme na to, jak nakonfigurovat metody TableAdapter pro použití existujících nebo ručně vytvořených uložených procedur.
Poznámka
Podívejte se na blogovou položku Roba Howarda Nepoužívejte uložené procedury ještě? a franse Bouma s blogovou položkou Uložené procedury jsou špatné, M Kay? pro živou debatu o výhodách a nevýhodách uložených procedur a ad hoc SQL.
Základní informace o uložených procedurách
Funkce jsou konstruktor společný pro všechny programovací jazyky. Funkce je kolekce příkazů, které se spouští při zavolání funkce. Funkce můžou přijímat vstupní parametry a volitelně můžou vrátit hodnotu. Uložené procedury jsou databázové konstrukce, které sdílejí mnoho podobností s funkcemi v programovacích jazycích. Uložená procedura se skládá ze sady příkazů T-SQL, které se spustí při volání uložené procedury. Uložená procedura může přijímat nula až mnoho vstupních parametrů a může vracet skalární hodnoty, výstupní parametry nebo nejčastěji sady výsledků z SELECT
dotazů.
Poznámka
Uložené procedury se často označují jako sprocs nebo SPS .
Uložené procedury se vytvářejí pomocí CREATE PROCEDURE
příkazu T-SQL. Například následující skript T-SQL vytvoří uloženou proceduru s názvemGetProductsByCategoryID
, která přijme jeden parametr s názvem @CategoryID
a vrátí ProductID
pole , ProductName
UnitPrice
, a Discontinued
z těchto sloupců v Products
tabulce, které mají odpovídající CategoryID
hodnotu:
CREATE PROCEDURE GetProductsByCategoryID
(
@CategoryID int
)
AS
SELECT ProductID, ProductName, UnitPrice, Discontinued
FROM Products
WHERE CategoryID = @CategoryID
Po vytvoření této uložené procedury je možné ji volat pomocí následující syntaxe:
EXEC GetProductsByCategory categoryID
Poznámka
V dalším kurzu prozkoumáme vytváření uložených procedur prostřednictvím integrovaného vývojového prostředí sady Visual Studio. Pro účely tohoto kurzu však necháme průvodce TableAdapter automaticky vygenerovat uložené procedury.
Kromě jednoduchého vrácení dat se uložené procedury často používají k provádění více databázových příkazů v rámci jedné transakce. Uložená procedura s názvem DeleteCategory
může například přijmout @CategoryID
parametr a provést dva DELETE
příkazy: první pro odstranění souvisejících produktů a druhý odstraňují zadanou kategorii. Více příkazů v rámci uložené procedury není automaticky zabaleno do transakce. Je potřeba vydat další příkazy T-SQL, aby se zajistilo, že se s více příkazy uložené procedury bude zacházet jako s atomické operace. V následujícím kurzu se dozvíme, jak zabalit příkazy uložené procedury do rozsahu transakce.
Při použití uložených procedur v rámci architektury metody data Access Layer místo vystavení příkazu SQL ad hoc vyvolají konkrétní uloženou proceduru. Tím se centralizuje umístění spuštěných příkazů SQL (v databázi) a nedefinuje se v rámci architektury aplikace. Tato centralizace pravděpodobně usnadňuje hledání, analýzu a ladění dotazů a poskytuje mnohem jasnější představu o tom, kde a jak se databáze používá.
Další informace o základech uložených procedur najdete v části Další informace na konci tohoto kurzu.
Krok 1: Vytvoření webových stránek Advanced Data Access Layer Scenarios
Než začneme diskutovat o vytvoření DAL pomocí uložených procedur, pojďme nejprve chvíli vytvořit ASP.NET stránky v našem webovém projektu, které budeme potřebovat pro tento a několik dalších kurzů. Začněte přidáním nové složky s názvem AdvancedDAL
. Dále do této složky přidejte následující ASP.NET stránky a nezapomeňte přidružit každou stránku ke Site.master
stránce předlohy:
Default.aspx
NewSprocs.aspx
ExistingSprocs.aspx
JOINs.aspx
AddingColumns.aspx
ComputedColumns.aspx
EncryptingConfigSections.aspx
ManagedFunctionsAndSprocs.aspx
Obrázek 1: Přidání stránek ASP.NET pro scénáře pokročilého přístupu k datům
Stejně jako v ostatních složkách Default.aspx
bude ve AdvancedDAL
složce seznam kurzů ve své části. Vzpomeňte si SectionLevelTutorialListing.ascx
, že tuto funkci poskytuje uživatelský ovládací prvek. Proto přidejte tento uživatelský ovládací prvek do Default.aspx
tak, že ho přetáhnete z Průzkumník řešení do zobrazení Návrh stránky.
Obrázek 2: Přidání SectionLevelTutorialListing.ascx
uživatelského ovládacího prvku do Default.aspx
(kliknutím zobrazíte obrázek v plné velikosti)
Nakonec přidejte tyto stránky jako položky do Web.sitemap
souboru. Konkrétně za položku Práce s daty <siteMapNode>
v dávce přidejte následující kód:
<siteMapNode url="~/AdvancedDAL/Default.aspx"
title="Advanced DAL Scenarios"
description="Explore a number of advanced Data Access Layer scenarios.">
<siteMapNode url="~/AdvancedDAL/NewSprocs.aspx"
title="Creating New Stored Procedures for TableAdapters"
description="Learn how to have the TableAdapter wizard automatically
create and use stored procedures." />
<siteMapNode url="~/AdvancedDAL/ExistingSprocs.aspx"
title="Using Existing Stored Procedures for TableAdapters"
description="See how to plug existing stored procedures into a
TableAdapter." />
<siteMapNode url="~/AdvancedDAL/JOINs.aspx"
title="Returning Data Using JOINs"
description="Learn how to augment your DataTables to work with data
returned from multiple tables via a JOIN query." />
<siteMapNode url="~/AdvancedDAL/AddingColumns.aspx"
title="Adding DataColumns to a DataTable"
description="Master adding new columns to an existing DataTable." />
<siteMapNode url="~/AdvancedDAL/ComputedColumns.aspx"
title="Working with Computed Columns"
description="Explore how to work with computed columns when using
Typed DataSets." />
<siteMapNode url="~/AdvancedDAL/EncryptingConfigSections.aspx"
title="Protected Connection Strings in Web.config"
description="Protect your connection string information in
Web.config using encryption." />
<siteMapNode url="~/AdvancedDAL/ManagedFunctionsAndSprocs.aspx"
title="Creating Managed SQL Functions and Stored Procedures"
description="See how to create SQL functions and stored procedures
using managed code." />
</siteMapNode>
Po aktualizaci Web.sitemap
si chvíli prohlédněte web kurzů v prohlížeči. Nabídka na levé straně teď obsahuje položky pro kurzy pokročilých scénářů DAL.
Obrázek 3: Mapa webu teď obsahuje položky pro kurzy pokročilých scénářů DAL
Krok 2: Konfigurace nástroje TableAdapter pro vytvoření nových uložených procedur
Chcete-li si předvést vytvoření vrstvy přístupu k datům, která místo příkazů SQL ad hoc používá uložené procedury, vytvořte novou typovou sadu dat ve ~/App_Code/DAL
složce s názvem NorthwindWithSprocs.xsd
. Vzhledem k tomu, že jsme tento proces podrobně probrali v předchozích kurzech, budeme rychle pokračovat v těchto krocích. Pokud se zaseknete nebo potřebujete další podrobné pokyny k vytvoření a konfiguraci typové sady dat, projděte si kurz Vytvoření vrstvy přístupu k datům .
Přidejte do projektu novou datovou sadu tak, že kliknete pravým tlačítkem na DAL
složku, zvolíte Přidat novou položku a vyberete šablonu DataSet, jak je znázorněno na obrázku 4.
Obrázek 4: Přidání nové zadané datové sady do projektu s názvem NorthwindWithSprocs.xsd
(kliknutím zobrazíte obrázek v plné velikosti)
Tím se vytvoří nová sada Typed DataSet, otevře se její Designer, vytvoří se nový objekt TableAdapter a spustí se Průvodce konfigurací objektu TableAdapter. První krok Průvodce konfigurací nástroje TableAdapter nás vyzve, abychom vybrali databázi, se kterým chcete pracovat. V rozevíracím seznamu by měly být uvedené připojovací řetězec k databázi Northwind. Vyberte tuto možnost a klikněte na Další.
Na této další obrazovce můžeme zvolit, jak má TableAdapter přistupovat k databázi. V předchozích kurzech jsme vybrali první možnost Použití příkazů SQL. Pro účely tohoto kurzu vyberte druhou možnost Vytvořit nové uložené procedury a klikněte na Další.
Obrázek 5: Řekněte sadě TableAdapter, aby vytvořil nové uložené procedury (kliknutím zobrazíte obrázek v plné velikosti)
Stejně jako u použití ad hoc příkazů SQL jsme v následujícím kroku požádáni o zadání SELECT
příkazu pro hlavní dotaz TableAdapter s. Ale místo použití zde zadaného SELECT
příkazu k provedení ad hoc dotazu přímo, průvodce TableAdapter s vytvoří uloženou proceduru, která obsahuje tento SELECT
dotaz.
Pro tento tableAdapter použijte následující SELECT
dotaz:
SELECT ProductID, ProductName, SupplierID, CategoryID,
QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder,
ReorderLevel, Discontinued
FROM Products
Obrázek 6: Zadejte SELECT
dotaz (kliknutím zobrazíte obrázek v plné velikosti)
Poznámka
Výše uvedený dotaz se mírně liší od hlavního ProductsTableAdapter
dotazu v Northwind
zadané datové sadě. Vzpomeňte si, že ProductsTableAdapter
sada Northwind
Typed DataSet obsahuje dva korelované poddotazy, které vrátí název kategorie a název společnosti pro každou kategorii produktu a dodavatele. V nadcházejícím kurzu Aktualizace objektu TableAdapter na použití sítí JOINs se podíváme na přidání těchto souvisejících dat do tohoto objektu TableAdapter.
Chvíli klikněte na tlačítko Upřesnit možnosti. Tady můžeme určit, jestli má průvodce také generovat příkazy insert, update a delete pro Objekt TableAdapter, jestli se má použít optimistická souběžnost a jestli se má po vložení a aktualizacích aktualizovat tabulka dat. Možnost Generovat příkazy Insert, Update a Delete je ve výchozím nastavení zaškrtnutá. Nechte ho zaškrtnuté. Pro účely tohoto kurzu ponechte možnost Použít optimistickou souběžnost nezaškrtnutou.
Při automatickém vytvoření uložených procedur průvodcem objektem TableAdapter se zdá, že možnost Aktualizovat tabulku dat je ignorována. Bez ohledu na to, jestli je toto políčko zaškrtnuté, výsledné uložené procedury vložení a aktualizace načtou právě vložený nebo aktualizovaný záznam, jak uvidíme v kroku 3.
Obrázek 7: Nechte zaškrtnutou možnost Generovat příkazy Insert, Update a Delete.
Poznámka
Pokud je zaškrtnuté políčko Použít optimistickou souběžnost, průvodce přidá do WHERE
klauzule další podmínky, které brání aktualizaci dat v případě změn v jiných polích. Další informace o používání integrované funkce řízení optimistické souběžnosti najdete v kurzu Implementace optimistické souběžnosti .
Po zadání SELECT
dotazu a potvrzení, že je zaškrtnutá možnost Generovat příkazy Insert, Update a Delete, klikněte na Další. Na další obrazovce na obrázku 8 se zobrazí výzva k zadání názvů uložených procedur, které průvodce vytvoří pro výběr, vložení, aktualizaci a odstranění dat. Změňte tyto názvy uložených procedur na Products_Select
, Products_Insert
, Products_Update
a Products_Delete
.
Obrázek 8: Přejmenování uložených procedur (kliknutím zobrazíte obrázek v plné velikosti)
Pokud chcete zobrazit T-SQL, který průvodce TableAdapter použije k vytvoření čtyř uložených procedur, klikněte na tlačítko Náhled skriptu SQL. V dialogovém okně Náhled skriptu SQL můžete skript uložit do souboru nebo ho zkopírovat do schránky.
Obrázek 9: Náhled skriptu SQL použitého ke generování uložených procedur
Po pojmenování uložených procedur klikněte na Další a pojmenujte odpovídající metody TableAdapter. Stejně jako při použití ad hoc příkazů SQL můžeme vytvořit metody, které vyplní existující tabulku DataTable nebo vrátí novou. Můžeme také určit, jestli má tableAdapter obsahovat DB-Direct vzor pro vkládání, aktualizaci a odstraňování záznamů. Nechte zaškrtnutá všechna tři políčka, ale přejmenujte metodu Return a DataTable na GetProducts
(jak je znázorněno na obrázku 10).
Obrázek 10: Pojmenujte metody Fill
a GetProducts
(kliknutím zobrazíte obrázek v plné velikosti)
Kliknutím na Další zobrazíte souhrn kroků, které průvodce provede. Dokončete průvodce kliknutím na tlačítko Dokončit. Po dokončení průvodce se vrátíte do Designer datové sady, která by teď měla obsahovat ProductsDataTable
.
Obrázek 11: DataSet s Designer Zobrazuje nově přidaný ProductsDataTable
obrázek (kliknutím zobrazíte obrázek v plné velikosti).
Krok 3: Prozkoumání nově vytvořených uložených procedur
Průvodce objektu TableAdapter použitý v kroku 2 automaticky vytvořil uložené procedury pro výběr, vložení, aktualizaci a odstranění dat. Tyto uložené procedury můžete zobrazit nebo upravit v sadě Visual Studio tak, že přejdete do Průzkumníka serveru a přejdete k podrobnostem do složky Uložené procedury databáze. Jak ukazuje obrázek 12, databáze Northwind obsahuje čtyři nové uložené procedury: Products_Delete
, Products_Insert
, Products_Select
a Products_Update
.
Obrázek 12: Čtyři uložené procedury vytvořené v kroku 2 najdete ve složce Uložených procedur databáze.
Poznámka
Pokud se Průzkumník serveru nezobrazuje, přejděte do nabídky Zobrazení a zvolte možnost Průzkumník serveru. Pokud nevidíte uložené procedury související s produktem přidané v kroku 2, zkuste kliknout pravým tlačítkem na složku Uložené procedury a zvolit Aktualizovat.
Chcete-li zobrazit nebo upravit uloženou proceduru, poklikejte na její název v Průzkumníku serveru nebo případně klikněte pravým tlačítkem na uloženou proceduru a zvolte Otevřít. Obrázek 13 znázorňuje uloženou proceduru Products_Delete
při otevření.
Obrázek 13: Uložené procedury je možné otevřít a upravit v sadě Visual Studio (kliknutím zobrazíte obrázek v plné velikosti)
Obsah uložených procedur a Products_Delete
Products_Select
je poměrně jednoduchý. Naproti Products_Insert
tomu uložené procedury a Products_Update
vyžadují bližší kontrolu, protože obě provádějí SELECT
prohlášení za svými INSERT
prohlášeními a UPDATE
. Uloženou proceduru tvoří Products_Insert
například následující SQL:
ALTER PROCEDURE dbo.Products_Insert
(
@ProductName nvarchar(40),
@SupplierID int,
@CategoryID int,
@QuantityPerUnit nvarchar(20),
@UnitPrice money,
@UnitsInStock smallint,
@UnitsOnOrder smallint,
@ReorderLevel smallint,
@Discontinued bit
)
AS
SET NOCOUNT OFF;
INSERT INTO [Products] ([ProductName], [SupplierID], [CategoryID], [QuantityPerUnit],
[UnitPrice], [UnitsInStock], [UnitsOnOrder], [ReorderLevel], [Discontinued])
VALUES (@ProductName, @SupplierID, @CategoryID, @QuantityPerUnit, @UnitPrice,
@UnitsInStock, @UnitsOnOrder, @ReorderLevel, @Discontinued);
SELECT ProductID, ProductName, SupplierID, CategoryID, QuantityPerUnit, UnitPrice,
UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued
FROM Products
WHERE (ProductID = SCOPE_IDENTITY())
Uložená procedura přijímá jako vstupní parametry Products
sloupce vrácené dotazem SELECT
zadaným v průvodci TableAdapter a tyto hodnoty se používají v příkazu INSERT
. Za příkazem INSERT
se použije dotaz, který SELECT
vrátí Products
hodnoty sloupců (včetně ProductID
) nově přidaného záznamu. Tato funkce aktualizace je užitečná při přidávání nového záznamu pomocí vzoru Dávkové aktualizace, protože automaticky aktualizuje vlastnosti nově přidaných ProductRow
instancí ProductID
pomocí automaticky přidaných hodnot přiřazených databází.
Tuto funkci znázorňuje následující kód. Obsahuje ProductsTableAdapter
a ProductsDataTable
vytvořené pro NorthwindWithSprocs
typed dataSet. Nový produkt se přidá do databáze tak, že se vytvoří ProductsRow
instance, zadá se její hodnoty a zavolá metoda TableAdapter s Update
předáním ProductsDataTable
metody . Interně TableAdapter s Update
metoda vytvoří ProductsRow
výčet instancí v předané DataTable (v tomto příkladu je pouze jeden - ten, který jsme právě přidali) a provede příslušný příkaz insert, update nebo delete. V tomto případě Products_Insert
se spustí uložená procedura, která do Products
tabulky přidá nový záznam a vrátí podrobnosti o nově přidaném záznamu. Hodnota ProductsRow
instance s ProductID
se pak aktualizuje. Update
Po dokončení metody můžeme získat přístup k nově přidané hodnotě záznamu ProductID
ProductsRow
prostřednictvím vlastnosti sProductID
.
' Create the ProductsTableAdapter and ProductsDataTable
Dim productsAPI As New NorthwindWithSprocsTableAdapters.ProductsTableAdapter
Dim products As New NorthwindWithSprocs.ProductsDataTable
' Create a new ProductsRow instance and set its properties
Dim product As NorthwindWithSprocs.ProductsRow = products.NewProductsRow()
product.ProductName = "New Product"
product.CategoryID = 1 ' Beverages
product.Discontinued = False
' Add the ProductsRow instance to the DataTable
products.AddProductsRow(product)
' Update the DataTable using the Batch Update pattern
productsAPI.Update(products)
' At this point, we can determine the value of the newly-added record's ProductID
Dim newlyAddedProductIDValue as Integer = product.ProductID
Uložená procedura Products_Update
podobně obsahuje SELECT
příkaz za svým UPDATE
příkazem.
ALTER PROCEDURE dbo.Products_Update
(
@ProductName nvarchar(40),
@SupplierID int,
@CategoryID int,
@QuantityPerUnit nvarchar(20),
@UnitPrice money,
@UnitsInStock smallint,
@UnitsOnOrder smallint,
@ReorderLevel smallint,
@Discontinued bit,
@Original_ProductID int,
@ProductID int
)
AS
SET NOCOUNT OFF;
UPDATE [Products]
SET [ProductName] = @ProductName, [SupplierID] = @SupplierID,
[CategoryID] = @CategoryID, [QuantityPerUnit] = @QuantityPerUnit,
[UnitPrice] = @UnitPrice, [UnitsInStock] = @UnitsInStock,
[UnitsOnOrder] = @UnitsOnOrder, [ReorderLevel] = @ReorderLevel,
[Discontinued] = @Discontinued
WHERE (([ProductID] = @Original_ProductID));
SELECT ProductID, ProductName, SupplierID, CategoryID, QuantityPerUnit,
UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued
FROM Products
WHERE (ProductID = @ProductID)
Všimněte si, že tato uložená procedura obsahuje dva vstupní parametry pro ProductID
: @Original_ProductID
a @ProductID
. Tato funkce umožňuje scénáře, ve kterých může dojít ke změně primárního klíče. Například v databázi zaměstnanců může každý záznam zaměstnance používat jako primární klíč číslo sociálního pojištění zaměstnance. Aby bylo možné změnit stávající číslo sociálního pojištění zaměstnance, musí být zadáno nové i původní číslo sociálního pojištění. Products
Pro tabulku tato funkce není potřeba, protože ProductID
sloupec je IDENTITY
sloupec a nikdy by se neměl měnit. Příkaz v uložené proceduře Products_Update
ve skutečnosti UPDATE
neobsahuje ProductID
sloupec v seznamu sloupců. I když @Original_ProductID
se tedy používá v UPDATE
klauzuli statement s WHERE
, je pro Products
tabulku nadbytečná a může být nahrazena parametrem @ProductID
. Při úpravě parametrů uložené procedury je důležité, aby byly aktualizovány také metody TableAdapter, které tuto uloženou proceduru používají.
Krok 4: Úprava parametrů uložené procedury a aktualizace objektu TableAdapter
Vzhledem k tomu, že @Original_ProductID
je parametr nadbytečný, pojďme ho Products_Update
z uložené procedury úplně odebrat. Otevřete uloženou proceduru Products_Update
@Original_ProductID
, odstraňte parametr a v WHERE
klauzuli UPDATE
příkazu změňte použitý název parametru z @Original_ProductID
na @ProductID
. Po provedení těchto změn by měl T-SQL v rámci uložené procedury vypadat takto:
ALTER PROCEDURE dbo.Products_Update
(
@ProductName nvarchar(40),
@SupplierID int,
@CategoryID int,
@QuantityPerUnit nvarchar(20),
@UnitPrice money,
@UnitsInStock smallint,
@UnitsOnOrder smallint,
@ReorderLevel smallint,
@Discontinued bit,
@ProductID int
)
AS
SET NOCOUNT OFF;
UPDATE [Products] SET [ProductName] = @ProductName, [SupplierID] = @SupplierID,
[CategoryID] = @CategoryID, [QuantityPerUnit] = @QuantityPerUnit,
[UnitPrice] = @UnitPrice, [UnitsInStock] = @UnitsInStock,
[UnitsOnOrder] = @UnitsOnOrder, [ReorderLevel] = @ReorderLevel,
[Discontinued] = @Discontinued
WHERE (([ProductID] = @ProductID));
SELECT ProductID, ProductName, SupplierID, CategoryID, QuantityPerUnit,
UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued
FROM Products
WHERE (ProductID = @ProductID)
Pokud chcete tyto změny uložit do databáze, klikněte na panelu nástrojů na ikonu Uložit nebo stiskněte Ctrl+S. V tomto okamžiku Products_Update
uložená procedura neočekává @Original_ProductID
vstupní parametr, ale Objekt TableAdapter je nakonfigurován tak, aby takový parametr předal. Parametry, které objekt TableAdapter odešle uložené proceduřeProducts_Update
, můžete zobrazit tak, že v Designer Datové sady vyberete objekt TableAdapter, přejdete na okno Vlastnosti a kliknete na tři tečky v kolekci UpdateCommand
sParameters
. Zobrazí se dialogové okno Kolekce parametrů Editor zobrazené na obrázku 14.
Obrázek 14: Kolekce parametrů Editor Seznamy použitých parametrů předaných uložené proceduře Products_Update
Odsud můžete tento parametr odebrat jednoduše tak, že ho @Original_ProductID
vyberete ze seznamu členů a kliknete na tlačítko Odebrat.
Alternativně můžete aktualizovat parametry používané pro všechny metody tak, že kliknete pravým tlačítkem na objekt TableAdapter v Designer a zvolíte Konfigurovat. Zobrazí se průvodce konfigurací tableadapter, který zobrazí seznam uložených procedur používaných pro výběr, vložení, aktualizaci a odstranění spolu s parametry, které uložené procedury očekávají. Když kliknete na rozevírací seznam Aktualizovat, zobrazí Products_Update
se očekávané vstupní parametry uložených procedur, které už neobsahují @Original_ProductID
(viz Obrázek 15). Jednoduše klikněte na Dokončit a automaticky aktualizujte kolekci parametrů používanou objektem TableAdapter.
Obrázek 15: Alternativně můžete použít Průvodce konfigurací nástroje TableAdapter k aktualizaci kolekcí parametrů metod (kliknutím zobrazíte obrázek v plné velikosti).
Krok 5: Přidání dalších metod TableAdapter
Jak je znázorněno v kroku 2, při vytváření nového parametru TableAdapter je snadné nechat automaticky vygenerovat odpovídající uložené procedury. Totéž platí při přidávání dalších metod do objektu TableAdapter. Pro ilustraci přidáme metodu GetProductByProductID(productID)
do objektu vytvořeného ProductsTableAdapter
v kroku 2. Tato metoda vezme jako vstup ProductID
hodnotu a vrátí podrobnosti o zadaném produktu.
Začněte tak, že kliknete pravým tlačítkem na objekt TableAdapter a v místní nabídce zvolíte Přidat dotaz.
Obrázek 16: Přidání nového dotazu do vlastnosti TableAdapter
Tím se spustí Průvodce konfigurací dotazu TableAdapter, který nejprve zobrazí výzvu k přístupu k databázi pomocí parametru TableAdapter. Pokud chcete vytvořit novou uloženou proceduru, zvolte možnost Vytvořit novou uloženou proceduru a klikněte na Další.
Obrázek 17: Volba možnosti Vytvořit novou uloženou proceduru (kliknutím zobrazíte obrázek v plné velikosti)
Další obrazovka nás vyzve k určení typu dotazu, který se má provést, zda vrátí sadu řádků nebo jednu skalární hodnotu, nebo provede UPDATE
příkaz , INSERT
nebo DELETE
. Vzhledem k tomu, že GetProductByProductID(productID)
metoda vrátí řádek, nechte vybranou možnost VYBRAT, která vrací řádek a stiskněte Další.
Obrázek 18: Výběr možnosti SELECT, která vrátí řádek (kliknutím zobrazíte obrázek v plné velikosti)
Na další obrazovce se zobrazí hlavní dotaz objektu TableAdapter, který uvádí pouze název uložené procedury (dbo.Products_Select
). Nahraďte název uložené procedury následujícím SELECT
příkazem, který vrátí všechna pole produktů pro zadaný produkt:
SELECT ProductID, ProductName, SupplierID, CategoryID,
QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder,
ReorderLevel, Discontinued
FROM Products
WHERE ProductID = @ProductID
Obrázek 19: Nahrazení názvu uložené procedury dotazem SELECT
(kliknutím zobrazíte obrázek v plné velikosti)
Následující obrazovka vás vyzve k pojmenování uložené procedury, která se vytvoří. Zadejte název Products_SelectByProductID
a klikněte na Další.
Obrázek 20: Pojmenujte novou uloženou proceduru Products_SelectByProductID
(kliknutím zobrazíte obrázek v plné velikosti)
Poslední krok průvodce nám umožňuje změnit vygenerované názvy metod a určit, jestli se má použít vzor Vyplnit datovou tabulku, Vrátit vzor DataTable, nebo obojí. U této metody nechte zaškrtnuté obě možnosti, ale přejmenujte metody na FillByProductID
a GetProductByProductID
. Kliknutím na Tlačítko Další zobrazíte souhrn kroků, které průvodce provede, a kliknutím na Tlačítko Dokončit průvodce dokončete.
Obrázek 21: Přejmenujte metody TableAdapter na FillByProductID
a GetProductByProductID
(Kliknutím zobrazíte obrázek v plné velikosti)
Po dokončení průvodce má Objekt TableAdapter k dispozici novou metodu, GetProductByProductID(productID)
která při vyvolání spustí uloženou proceduru Products_SelectByProductID
, která byla právě vytvořena. Chvíli si prohlédněte tuto novou uloženou proceduru v Průzkumníku serveru tak, že přejdete do složky Uložené procedury a otevřete Products_SelectByProductID
ji (pokud ji nevidíte, klikněte pravým tlačítkem na složku Uložené procedury a zvolte Aktualizovat).
Všimněte si, že uložená SelectByProductID
procedura přijímá @ProductID
jako vstupní parametr a spouští SELECT
příkaz, který jsme zadali v průvodci.
ALTER PROCEDURE dbo.Products_SelectByProductID
(
@ProductID int
)
AS
SET NOCOUNT ON;
SELECT ProductID, ProductName, SupplierID, CategoryID,
QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder,
ReorderLevel, Discontinued
FROM Products
WHERE ProductID = @ProductID
Krok 6: Vytvoření třídy vrstvy obchodní logiky
V rámci série kurzů jsme se snažili zachovat vrstvenou architekturu, ve které prezentační vrstva provedla všechny své volání do vrstvy obchodní logiky (BLL). Aby bylo možné dodržet toto rozhodnutí o návrhu, musíme nejprve vytvořit třídu BLL pro novou Typed DataSet, abychom měli přístup k datům produktu z prezentační vrstvy.
Ve složce vytvořte nový soubor třídy s názvem ProductsBLLWithSprocs.vb
~/App_Code/BLL
a přidejte do něj následující kód:
Imports NorthwindWithSprocsTableAdapters
<System.ComponentModel.DataObject()> _
Public Class ProductsBLLWithSprocs
Private _productsAdapter As ProductsTableAdapter = Nothing
Protected ReadOnly Property Adapter() As ProductsTableAdapter
Get
If _productsAdapter Is Nothing Then
_productsAdapter = New ProductsTableAdapter()
End If
Return _productsAdapter
End Get
End Property
<System.ComponentModel.DataObjectMethodAttribute _
(System.ComponentModel.DataObjectMethodType.Select, True)> _
Public Function GetProducts() As NorthwindWithSprocs.ProductsDataTable
Return Adapter.GetProducts()
End Function
<System.ComponentModel.DataObjectMethodAttribute _
(System.ComponentModel.DataObjectMethodType.Select, False)> _
Public Function GetProductByProductID(ByVal productID As Integer) _
As NorthwindWithSprocs.ProductsDataTable
Return Adapter.GetProductByProductID(productID)
End Function
<System.ComponentModel.DataObjectMethodAttribute _
(System.ComponentModel.DataObjectMethodType.Insert, True)> _
Public Function AddProduct _
(ByVal productName As String, ByVal supplierID As Nullable(Of Integer), _
ByVal categoryID As Nullable(Of Integer), ByVal quantityPerUnit As String, _
ByVal unitPrice As Nullable(Of Decimal), _
ByVal unitsInStock As Nullable(Of Short), _
ByVal unitsOnOrder As Nullable(Of Short), _
ByVal reorderLevel As Nullable(Of Short), _
ByVal discontinued As Boolean) _
As Boolean
' Create a new ProductRow instance
Dim products As New NorthwindWithSprocs.ProductsDataTable()
Dim product As NorthwindWithSprocs.ProductsRow = products.NewProductsRow()
product.ProductName = productName
If Not supplierID.HasValue Then
product.SetSupplierIDNull()
Else
product.SupplierID = supplierID.Value
End If
If Not categoryID.HasValue Then
product.SetCategoryIDNull()
Else
product.CategoryID = categoryID.Value
End If
If quantityPerUnit Is Nothing Then
product.SetQuantityPerUnitNull()
Else
product.QuantityPerUnit = quantityPerUnit
End If
If Not unitPrice.HasValue Then
product.SetUnitPriceNull()
Else
product.UnitPrice = unitPrice.Value
End If
If Not unitsInStock.HasValue Then
product.SetUnitsInStockNull()
Else
product.UnitsInStock = unitsInStock.Value
End If
If Not unitsOnOrder.HasValue Then
product.SetUnitsOnOrderNull()
Else
product.UnitsOnOrder = unitsOnOrder.Value
End If
If Not reorderLevel.HasValue Then
product.SetReorderLevelNull()
Else
product.ReorderLevel = reorderLevel.Value
End If
product.Discontinued = discontinued
' Add the new product
products.AddProductsRow(product)
Dim rowsAffected As Integer = Adapter.Update(products)
' Return true if precisely one row was inserted, otherwise false
Return rowsAffected = 1
End Function
<System.ComponentModel.DataObjectMethodAttribute _
(System.ComponentModel.DataObjectMethodType.Update, True)> _
Public Function UpdateProduct
(ByVal productName As String, ByVal supplierID As Nullable(Of Integer), _
ByVal categoryID As Nullable(Of Integer), ByVal quantityPerUnit As String, _
ByVal unitPrice As Nullable(Of Decimal), _
ByVal unitsInStock As Nullable(Of Short), _
ByVal unitsOnOrder As Nullable(Of Short), _
ByVal reorderLevel As Nullable(Of Short), _
ByVal discontinued As Boolean, ByVal productID As Integer) _
As Boolean
Dim products As NorthwindWithSprocs.ProductsDataTable = _
Adapter.GetProductByProductID(productID)
If products.Count = 0 Then
' no matching record found, return false
Return False
End If
Dim product As NorthwindWithSprocs.ProductsRow = products(0)
product.ProductName = productName
If Not supplierID.HasValue Then
product.SetSupplierIDNull()
Else
product.SupplierID = supplierID.Value
End If
If Not categoryID.HasValue Then
product.SetCategoryIDNull()
Else
product.CategoryID = categoryID.Value
End If
If quantityPerUnit Is Nothing Then
product.SetQuantityPerUnitNull()
Else
product.QuantityPerUnit = quantityPerUnit
End If
If Not unitPrice.HasValue Then
product.SetUnitPriceNull()
Else
product.UnitPrice = unitPrice.Value
End If
If Not unitsInStock.HasValue Then
product.SetUnitsInStockNull()
Else
product.UnitsInStock = unitsInStock.Value
End If
If Not unitsOnOrder.HasValue Then
product.SetUnitsOnOrderNull()
Else
product.UnitsOnOrder = unitsOnOrder.Value
End If
If Not reorderLevel.HasValue Then
product.SetReorderLevelNull()
Else
product.ReorderLevel = reorderLevel.Value
End If
product.Discontinued = discontinued
' Update the product record
Dim rowsAffected As Integer = Adapter.Update(product)
' Return true if precisely one row was updated, otherwise false
Return rowsAffected = 1
End Function
<System.ComponentModel.DataObjectMethodAttribute _
(System.ComponentModel.DataObjectMethodType.Delete, True)> _
Public Function DeleteProduct(ByVal productID As Integer) As Boolean
Dim rowsAffected As Integer = Adapter.Delete(productID)
' Return true if precisely one row was deleted, otherwise false
Return rowsAffected = 1
End Function
End Class
Tato třída napodobuje ProductsBLL
sémantiku třídy z předchozích kurzů, ale používá ProductsTableAdapter
objekty a ProductsDataTable
ze NorthwindWithSprocs
sady DataSet. Například místo toho, aby na začátku souboru třídy měla Imports NorthwindTableAdapters
příkaz jako , ProductsBLLWithSprocs
třída používá Imports NorthwindWithSprocsTableAdapters
.ProductsBLL
Podobně ProductsDataTable
objekty a ProductsRow
použité v této třídě mají předponu NorthwindWithSprocs
oboru názvů. Třída ProductsBLLWithSprocs
poskytuje dvě metody přístupu k datům GetProducts
, a GetProductByProductID
metody a metody pro přidání, aktualizaci a odstranění jedné instance produktu.
Krok 7: Práce seNorthwindWithSprocs
sadou dat z prezentační vrstvy
V tomto okamžiku jsme vytvořili dal, který používá uložené procedury pro přístup k podkladovým datům databáze a jejich úpravu. Vytvořili jsme také základní metodu BLL s metodami pro načtení všech produktů nebo konkrétního produktu spolu s metodami pro přidávání, aktualizaci a odstraňování produktů. Chcete-li tento kurz zaokrouhlit, pojďme vytvořit ASP.NET stránku, která používá třídu BLL s ProductsBLLWithSprocs
k zobrazení, aktualizaci a odstraňování záznamů.
NewSprocs.aspx
Otevřete stránku ve AdvancedDAL
složce a přetáhněte objekt GridView z panelu nástrojů do Designer a pojměte ho Products
. Z inteligentní značky GridView zvolte jeho vazbu na nový ObjectDataSource s názvem ProductsDataSource
. Nakonfigurujte ObjectDataSource tak, aby používal třídu ProductsBLLWithSprocs
, jak je znázorněno na obrázku 22.
Obrázek 22: Konfigurace objektu ObjectDataSource pro použití ProductsBLLWithSprocs
třídy (kliknutím zobrazíte obrázek v plné velikosti)
Rozevírací seznam na kartě SELECT má dvě možnosti a GetProducts
GetProductByProductID
. Vzhledem k tomu, že chceme zobrazit všechny produkty v GridView, zvolte metodu GetProducts
. Rozevírací seznamy na kartách UPDATE, INSERT a DELETE mají pouze jednu metodu. Ujistěte se, že každý z těchto rozevíracích seznamů má vybranou příslušnou metodu, a klikněte na Dokončit.
Po dokončení průvodce ObjectDataSource přidá Visual Studio do pole GridView pro data produktu BoundFields a CheckBoxField. Zapněte předdefinované funkce pro úpravy a odstraňování v GridView zaškrtnutím možností Povolit úpravy a Povolit odstranění, které jsou přítomné v inteligentní značce.
Obrázek 23: Stránka obsahuje objekt GridView s povolenou podporou úprav a odstraňování (kliknutím zobrazíte obrázek v plné velikosti)
Jak jsme probrali v předchozích kurzech, sada Visual Studio nastaví OldValuesParameterFormatString
po dokončení průvodce ObjectDataSource s vlastnost na original_{0}. Aby funkce pro úpravu dat fungovaly správně s parametry očekávanými metodami v naší BLL, musí se vrátit na výchozí hodnotu {0} . Proto nezapomeňte vlastnost nastavit OldValuesParameterFormatString
na {0} nebo ji úplně odebrat z deklarativní syntaxe.
Po dokončení průvodce Konfigurovat zdroj dat, zapnutí úprav a odstranění podpory v GridView a vrácení vlastnosti ObjectDataSource s OldValuesParameterFormatString
na výchozí hodnotu by deklarativní značky stránky měly vypadat podobně jako následující:
<asp:GridView ID="Products" runat="server" AutoGenerateColumns="False"
DataKeyNames="ProductID" DataSourceID="ProductsDataSource">
<Columns>
<asp:CommandField ShowDeleteButton="True" ShowEditButton="True" />
<asp:BoundField DataField="ProductID" HeaderText="ProductID"
InsertVisible="False" ReadOnly="True"
SortExpression="ProductID" />
<asp:BoundField DataField="ProductName" HeaderText="ProductName"
SortExpression="ProductName" />
<asp:BoundField DataField="SupplierID" HeaderText="SupplierID"
SortExpression="SupplierID" />
<asp:BoundField DataField="CategoryID" HeaderText="CategoryID"
SortExpression="CategoryID" />
<asp:BoundField DataField="QuantityPerUnit" HeaderText="QuantityPerUnit"
SortExpression="QuantityPerUnit" />
<asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice"
SortExpression="UnitPrice" />
<asp:BoundField DataField="UnitsInStock" HeaderText="UnitsInStock"
SortExpression="UnitsInStock" />
<asp:BoundField DataField="UnitsOnOrder" HeaderText="UnitsOnOrder"
SortExpression="UnitsOnOrder" />
<asp:BoundField DataField="ReorderLevel" HeaderText="ReorderLevel"
SortExpression="ReorderLevel" />
<asp:CheckBoxField DataField="Discontinued" HeaderText="Discontinued"
SortExpression="Discontinued" />
</Columns>
</asp:GridView>
<asp:ObjectDataSource ID="ProductsDataSource" runat="server"
DeleteMethod="DeleteProduct" InsertMethod="AddProduct"
SelectMethod="GetProducts" TypeName="ProductsBLLWithSprocs"
UpdateMethod="UpdateProduct">
<DeleteParameters>
<asp:Parameter Name="productID" Type="Int32" />
</DeleteParameters>
<UpdateParameters>
<asp:Parameter Name="productName" Type="String" />
<asp:Parameter Name="supplierID" Type="Int32" />
<asp:Parameter Name="categoryID" Type="Int32" />
<asp:Parameter Name="quantityPerUnit" Type="String" />
<asp:Parameter Name="unitPrice" Type="Decimal" />
<asp:Parameter Name="unitsInStock" Type="Int16" />
<asp:Parameter Name="unitsOnOrder" Type="Int16" />
<asp:Parameter Name="reorderLevel" Type="Int16" />
<asp:Parameter Name="discontinued" Type="Boolean" />
<asp:Parameter Name="productID" Type="Int32" />
</UpdateParameters>
<InsertParameters>
<asp:Parameter Name="productName" Type="String" />
<asp:Parameter Name="supplierID" Type="Int32" />
<asp:Parameter Name="categoryID" Type="Int32" />
<asp:Parameter Name="quantityPerUnit" Type="String" />
<asp:Parameter Name="unitPrice" Type="Decimal" />
<asp:Parameter Name="unitsInStock" Type="Int16" />
<asp:Parameter Name="unitsOnOrder" Type="Int16" />
<asp:Parameter Name="reorderLevel" Type="Int16" />
<asp:Parameter Name="discontinued" Type="Boolean" />
</InsertParameters>
</asp:ObjectDataSource>
V tomto okamžiku bychom mohli editovat GridView přizpůsobením rozhraní pro úpravy tak, aby zahrnovalo ověření, nechat CategoryID
sloupce a SupplierID
vykreslit jako DropDownLists atd. K tlačítku Odstranit bychom také mohli přidat potvrzení na straně klienta a doporučujeme vám, abyste si vzali čas na implementaci těchto vylepšení. Vzhledem k tomu, že tato témata byla popsána v předchozích kurzech, nebudeme je zde znovu probrat.
Bez ohledu na to, jestli gridview vylepšíte nebo ne, otestujte základní funkce stránky v prohlížeči. Jak ukazuje obrázek 24, stránka obsahuje seznam produktů v zobrazení GridView, který poskytuje možnosti pro úpravy a odstraňování jednotlivých řádků.
Obrázek 24: Produkty lze zobrazit, upravit a odstranit z GridView (kliknutím zobrazíte obrázek v plné velikosti)
Souhrn
TableAdaptery v typed dataset mají přístup k datům z databáze pomocí ad hoc příkazů SQL nebo prostřednictvím uložených procedur. Při práci s uloženými procedurami je možné použít existující uložené procedury nebo průvodce TableAdapter může být instruován k vytvoření nových uložených procedur založených SELECT
na dotazu. V tomto kurzu jsme prozkoumali, jak pro nás automaticky vytvořit uložené procedury.
Automatické vygenerování uložených procedur sice šetří čas, ale v některých případech není uložená procedura vytvořená průvodcem v souladu s tím, co bychom sami vytvořili. Jedním z příkladů je uložená Products_Update
procedura, která očekávala vstupní parametry a i @Original_ProductID
@ProductID
když @Original_ProductID
byl parametr nadbytečný.
V mnoha scénářích je možné, že uložené procedury již byly vytvořeny, nebo je můžeme chtít sestavit ručně, abychom měli větší úroveň kontroly nad příkazy uložených procedur. V obou případech bychom chtěli dát objektu TableAdapter pokyn, aby pro své metody používal existující uložené procedury. V dalším kurzu se dozvíme, jak toho dosáhnout.
Šťastné programování!
Další čtení
Další informace o tématech probíraných v tomto kurzu najdete v následujících zdrojích informací:
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 najít na mitchell@4GuysFromRolla.comadrese . nebo prostřednictvím jeho blogu, který najdete na http://ScottOnWriting.NETadrese .
Zvláštní poděkování
Tato série kurzů byla zkontrolována mnoha užitečnými recenzenty. Hlavním recenzentem pro tento kurz byl Hilton Geisenow. Chcete si projít moje nadcházející články na WEBU MSDN? Pokud ano, dejte mi čáru na mitchell@4GuysFromRolla.comadresu .
Váš názor
https://aka.ms/ContentUserFeedback.
Připravujeme: V průběhu roku 2024 budeme postupně vyřazovat problémy z GitHub coby mechanismus zpětné vazby pro obsah a nahrazovat ho novým systémem zpětné vazby. Další informace naleznete v tématu:Odeslat a zobrazit názory pro