Sdílet prostřednictvím


Aktualizace komponenty TableAdapter kvůli použití příkazů JOIN (C#)

od Scotta Mitchella

Stáhnout PDF

Při práci s databází je běžné požadovat data, která jsou rozložená do více tabulek. K načtení dat ze dvou různých tabulek můžeme použít buď korelovaný poddotaz, nebo operaci JOIN. V tomto kurzu porovnáváme korelované poddotazy a syntaxi JOIN před tím, než se podíváme na to, jak vytvořit Objekt TableAdapter, který obsahuje join v hlavním dotazu.

Úvod

U relačních databází jsou data, se kterými chceme pracovat, často rozložena do více tabulek. Například při zobrazení informací o produktech, které pravděpodobně chceme zobrazit, zobrazíme seznam odpovídajících kategorií produktů a názvů dodavatelů. Tabulka Products obsahuje hodnoty CategoryID a SupplierID, ale skutečné názvy kategorií a dodavatelů jsou v tabulkách Categories a Suppliers, v tomto pořadí.

K načtení informací z jiné související tabulky můžeme použít buď korelované poddotazy, nebo JOINs. Korelovaný poddotaz je vnořený SELECT dotaz, který odkazuje na sloupce ve vnějším dotazu. Například v kurzu Vytvoření vrstvy přístupu k datům jsme v hlavním dotazu použili dva korelované poddotazy ProductsTableAdapter k vrácení kategorií a názvů dodavatelů pro každý produkt. A JOIN je konstruktor SQL, který slučuje související řádky ze dvou různých tabulek. V kurzu Dotazování dat pomocí ovládacího prvku SqlDataSource jsme použili JOIN k zobrazení informací o kategoriích společně s jednotlivými produkty.

Důvodem, proč jsme se zdrželi použití JOIN s objekty TableAdapters, je způsoben omezeními v průvodci TableAdapter s automaticky vygenerovat odpovídající INSERT, UPDATE, a DELETE příkazy. Konkrétně, pokud hlavní dotaz TableAdapter obsahuje nějaké JOIN s, TableAdapter nemůže automaticky vytvořit ad hoc příkazy SQL nebo uložené procedury pro své InsertCommand, UpdateCommanda DeleteCommand vlastnosti.

V tomto kurzu krátce porovnáme a rozlišíme korelované poddotazy a JOIN s, předtím než prozkoumáme, jak vytvořit TableAdapter, který zahrnuje JOIN s ve svém hlavním dotazu.

Porovnání a kontrastování korelovaných poddotazů aJOIN s

Vzpomeňte si, že ProductsTableAdapter vytvořený v prvním kurzu v Northwind sadě dat používá korelované poddotazy, aby vrátil odpovídající kategorii a jméno dodavatele pro každý produkt. Hlavní ProductsTableAdapter dotaz je uvedený níže.

SELECT ProductID, ProductName, SupplierID, CategoryID, 
       QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder, 
       ReorderLevel, Discontinued,
       (SELECT CategoryName FROM Categories WHERE Categories.CategoryID = 
            Products.CategoryID) as CategoryName, 
       (SELECT CompanyName FROM Suppliers WHERE Suppliers.SupplierID = 
            Products.SupplierID) as SupplierName
FROM Products

Dva korelované poddotazy – (SELECT CategoryName FROM Categories WHERE Categories.CategoryID = Products.CategoryID) a (SELECT CompanyName FROM Suppliers WHERE Suppliers.SupplierID = Products.SupplierID) – jsou SELECT dotazy, které vrátí jednu hodnotu na produkt jako další sloupec v seznamu sloupců vnějšího příkazu SELECT.

Alternativně lze JOIN použít k vrácení dodavatele a názvu kategorie každého produktu. Následující dotaz vrátí stejný výstup jako výše uvedený, ale místo poddotazů používá JOIN :

SELECT ProductID, ProductName, Products.SupplierID, Products.CategoryID, 
       QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder, 
       ReorderLevel, Discontinued,
       Categories.CategoryName, 
       Suppliers.CompanyName as SupplierName
FROM Products
    LEFT JOIN Categories ON
        Categories.CategoryID = Products.CategoryID
    LEFT JOIN Suppliers ON
        Suppliers.SupplierID = Products.SupplierID

Sloučí JOIN záznamy z jedné tabulky se záznamy z jiné tabulky na základě určitých kritérií. Ve výše uvedeném dotazu například dává SQL Serveru pokyn, LEFT JOIN Categories ON Categories.CategoryID = Products.CategoryID aby sloučil každý záznam produktu se záznamem kategorie, jehož CategoryID hodnota odpovídá hodnotě produktu CategoryID . Sloučený výsledek nám umožňuje pracovat s odpovídajícími poli kategorií pro každý produkt (například CategoryName).

Poznámka:

JOIN s se běžně používají při dotazování dat z relačních databází. Pokud s syntaxí JOIN začínáte nebo potřebujete si její použití trochu osvojit, doporučuji tutoriál o spojování v SQL na W3 Schools. Stojí za to si také přečíst JOIN Základy a Základy poddotazůSQL Books Online.

Vzhledem k tomu, že JOIN a korelované poddotazy se dají použít k načtení souvisejících dat z jiných tabulek, mnoho vývojářů je ponecháno na pochybách a přemýšlí, jaký přístup použít. Všichni SQL guruy, se kterými jsem mluvil, řekli zhruba stejnou věc, že to ve skutečnosti nezáleží na výkonu, protože SQL Server bude produkovat zhruba identické plány provádění. Jejich rada je použít techniku, s kterou jste vy a váš tým nejvíce spokojeni. Stojí za zmínku, že po poskytnutí této rady tito experti okamžitě dávají přednost JOIN s před korelovanými poddotazy.

Při vytváření vrstvy přístupu k datům pomocí datových sad fungují nástroje při použití poddotazů lépe. Konkrétně průvodce TableAdapterem nebude automaticky generovat odpovídající INSERT, UPDATE a DELETE příkazy, pokud hlavní dotaz obsahuje JOIN, ale tyto příkazy automaticky vygeneruje, pokud jsou použity korelované poddotazy.

Pokud chcete tento nedostatek prozkoumat, vytvořte ve ~/App_Code/DAL složce dočasnou datovou sadu typed. Během průvodce konfigurací TableAdapter zvolte použití ad hoc příkazů SQL a zadejte následující SELECT dotaz (viz obrázek 1):

SELECT ProductID, ProductName, Products.SupplierID, Products.CategoryID, 
       QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder, 
       ReorderLevel, Discontinued,
       Categories.CategoryName, 
       Suppliers.CompanyName as SupplierName
FROM Products
    LEFT JOIN Categories ON
        Categories.CategoryID = Products.CategoryID
    LEFT JOIN Suppliers ON
        Suppliers.SupplierID = Products.SupplierID

Snímek obrazovky s oknem Průvodce konfigurací objektu TableAdaptor se zadaným dotazem obsahujícím záznamy JOIN

Obrázek 1: Zadejte hlavní dotaz, který obsahuje JOIN (kliknutím zobrazíte obrázek v plné velikosti).

Ve výchozím nastavení TableAdapter automaticky vytvoří INSERTUPDATE, a DELETE příkazy založené na hlavním dotazu. Pokud kliknete na tlačítko Upřesnit, uvidíte, že je tato funkce povolená. Navzdory tomuto nastavení nebude Objekt TableAdapter moci vytvořit INSERT, UPDATEa DELETE příkazy, protože hlavní dotaz obsahuje .JOIN

Snímek obrazovky s oknem Rozšířené možnosti a zaškrtnuté políčko Generovat příkazy Vložit, Aktualizovat a Odstranit.

Obrázek 2: Zadání hlavního dotazu, který obsahuje JOIN

Kliknutím na tlačítko Dokončit dokončete průvodce. V tuto chvíli bude návrhář datové sady obsahovat jeden TableAdapter a datovou tabulku se sloupci pro každé pole vrácené v seznamu sloupců dotazu SELECT. To zahrnuje CategoryName a SupplierName, jak ukazuje obrázek 3.

Tabulka DataTable obsahuje sloupec pro každé pole, které je vráceno v seznamu sloupců.

Obrázek 3: Datová tabulka obsahuje sloupec pro každé pole vrácené v seznamu sloupců

Zatímco DataTable má příslušné sloupce, TableAdapter nemá hodnoty pro své InsertCommand, UpdateCommanda DeleteCommand vlastnosti. Potvrďte to tak, že v Návrháři kliknete na objekt TableAdapter a pak přejdete do okna Vlastnosti. Tam uvidíte, že , InsertCommandUpdateCommanda DeleteCommand vlastnosti jsou nastaveny na (None) .

Vlastnosti InsertCommand, UpdateCommand a DeleteCommand jsou nastaveny na hodnotu (None).

Obrázek 4: Objekty InsertCommand, UpdateCommanda DeleteCommand vlastnosti jsou nastaveny na (Žádné) (Kliknutím zobrazíte obrázek v plné velikosti)

Abychom tento nedostatek obejít, můžeme ručně zadat příkazy a parametry SQL pro InsertCommandUpdateCommand, a DeleteCommand vlastnosti prostřednictvím okna Vlastnosti. Případně můžeme začít konfigurací hlavního dotazu TableAdapter tak, aby neobsadí žádnéJOIN z nich. To nám umožní, aby byly příkazy INSERT, UPDATE a DELETE pro nás automaticky generovány. Po dokončení průvodce bychom pak mohli ručně aktualizovat TableAdaptery SelectCommand z okna Vlastnosti, aby obsahovaly JOIN syntaxi.

I když tento přístup funguje, je velmi náchylný k chybám při použití ad-hoc SQL dotazů, protože kdykoli se hlavní dotaz TableAdapter znovu nakonfiguruje prostřednictvím průvodce, příkazy INSERT, UPDATE, a DELETE se znovu automaticky generují. To znamená, že všechna přizpůsobení, která jsme později provedli, by se ztratila, pokud jsme klikli pravým tlačítkem myši na TableAdapter, zvolili možnost Konfigurovat z místní nabídky a dokončili průvodce znovu.

Křehkost automaticky generovaných příkazů TableAdapter s, INSERT, UPDATE a DELETE, je naštěstí omezena na ad-hoc příkazy SQL. Pokud váš Objekt TableAdapter používá uložené procedury, můžete přizpůsobit SelectCommandInsertCommandUpdateCommand, nebo DeleteCommand uložené procedury a znovu spustit Průvodce konfigurací TableAdapter bez obav, že uložené procedury budou změněny.

V dalších několika krocích vytvoříme objekt TableAdapter, který zpočátku použije hlavní dotaz, který vynechá všechny JOIN s, aby se automaticky vygenerovaly odpovídající vložené, aktualizované a odstraněné uložené procedury. Poté aktualizujeme SelectCommand, aby používalo JOIN, které vrací další sloupce ze souvisejících tabulek. Nakonec vytvoříme odpovídající třídu vrstvy obchodní logiky a předvedeme použití třídy TableAdapter na webové stránce ASP.NET.

Krok 1: Vytvoření objektu TableAdapter pomocí zjednodušeného hlavního dotazu

Pro účely tohoto kurzu přidáme objekt TableAdapter a tabulku se silnými typy dat pro Employees tabulku v NorthwindWithSprocs datové sadě. Tabulka Employees obsahuje ReportsTo pole, které určuje EmployeeID manažera zaměstnance. Například zaměstnanec Anne Dodsworth má ReportTo hodnotu 5, což je EmployeeID Steven Buchanan. Anne se proto hlásí Stevenu, její nadřízenému. Spolu s vykazováním hodnoty jednotlivých zaměstnanců ReportsTo můžeme také chtít načíst jméno jejich nadřízeného. Toho lze dosáhnout pomocí JOIN. Použití JOIN při počáteční tvorbě TableAdapteru však zabraňuje automatickému vytvoření příslušných schopností pro vložení, aktualizaci a odstranění. Proto začneme vytvořením TableAdapteru, jehož hlavní dotaz neobsahuje žádné JOIN. Potom v kroku 2 aktualizujeme hlavní uloženou proceduru dotazu, abychom získali jméno správce prostřednictvím JOIN.

Začněte otevřením NorthwindWithSprocs datové sady ve ~/App_Code/DAL složce. Klikněte pravým tlačítkem myši v nástroji Návrhář, zvolte možnost "Přidat" z kontextové nabídky a vyberte položku "TableAdapter". Tím se spustí průvodce konfigurací TableAdapter. Jak je znázorněno na obrázku 5, průvodcem vytvořte nové uložené procedury a klikněte na Další. Pro připomenutí, jak vytvářet nové uložené procedury pomocí průvodce TableAdapter, naleznete informace v kurzu Vytváření nových uložených procedur pro TableAdaptery datové sady Typed DataSet.

Vyberte možnost Vytvořit nové uložené procedury.

Obrázek 5: Výběr možnosti Vytvořit nové uložené procedury (Kliknutím zobrazíte obrázek s plnou velikostí)

Pro hlavní dotaz TableAdapter použijte následující SELECT příkaz:

SELECT EmployeeID, LastName, FirstName, Title, HireDate, ReportsTo, Country
FROM Employees

Vzhledem k tomu, že tento dotaz neobsahuje žádné JOIN s, průvodce TableAdapter automaticky vytvoří uložené procedury s odpovídajícími INSERT, UPDATEa DELETE příkazy, stejně jako uloženou proceduru pro spuštění hlavního dotazu.

Následující krok nám umožňuje pojmenovat uložené procedury TableAdapter. Použijte názvy Employees_Select, Employees_Insert, Employees_Updatea Employees_Delete, jak je znázorněno na obrázku 6.

Pojmenujte uložené procedury TableAdapter s.

Obrázek 6: Pojmenování uložených procedur TableAdapter (kliknutím zobrazíte obrázek s plnou velikostí)

Poslední krok nás vyzve k pojmenování metod TableAdapter s. Používejte Fill a GetEmployees jako názvy metod. Nezapomeňte také ponechat metody Create pro odesílání aktualizací přímo do databáze (GenerateDBDirectMethods) zaškrtnuté.

Pojmenujte metody TableAdapter s Fill a GetEmployees

Obrázek 7: Pojmenování metod Fill TableAdapter s a GetEmployees (kliknutím zobrazíte obrázek s plnou velikostí)

Po dokončení průvodce chvíli prozkoumejte uložené procedury v databázi. Měli byste vidět čtyři nové: Employees_Select, Employees_Insert, Employees_Updatea Employees_Delete. Dále zkontrolujte právě vytvořené EmployeesDataTable a EmployeesTableAdapter. Tabulka DataTable obsahuje sloupec pro každé pole vrácené hlavním dotazem. Klikněte na Objekt TableAdapter a přejděte do okna Vlastnosti. Tam uvidíte, že vlastnosti InsertCommand, UpdateCommand a DeleteCommand jsou správně nakonfigurované pro volání odpovídajících uložených procedur.

TableAdapter zahrnuje možnosti vložení, aktualizace a odstranění.

Obrázek 8: Objekt TableAdapter obsahuje možnosti vložení, aktualizace a odstranění (kliknutím zobrazíte obrázek v plné velikosti).

Po automatickém vytvoření uložených procedur pro vložení, aktualizaci a odstranění a po správné konfiguraci vlastností InsertCommand, UpdateCommand a DeleteCommand jsme připraveni přizpůsobit uloženou proceduru SelectCommand, abychom vrátili další informace o manažerovi každého zaměstnance. Konkrétně potřebujeme aktualizovat uloženou proceduru Employees_Select tak, aby používala JOIN a vrátila manažerovy FirstName a LastName hodnoty. Po aktualizaci uložené procedury budeme muset aktualizovat tabulku DataTable tak, aby obsahovala tyto další sloupce. Tyto dva úkoly budeme řešit v krocích 2 a 3.

Krok 2: Přizpůsobení uložené procedury tak, aby zahrnovalaJOIN

Začněte tím, že přejdete do Průzkumníka serveru, rozbalíte složku Uložené procedury v databázi Northwind a otevřete uloženou proceduru Employees_Select. Pokud tuto uloženou proceduru nevidíte, klikněte pravým tlačítkem myši na složku Uložené procedury a zvolte Aktualizovat. Aktualizujte uloženou proceduru tak, aby používala LEFT JOIN k vrácení jména a příjmení manažera:

SELECT Employees.EmployeeID, Employees.LastName, 
       Employees.FirstName, Employees.Title, 
       Employees.HireDate, Employees.ReportsTo, 
       Employees.Country,
       Manager.FirstName as ManagerFirstName, 
       Manager.LastName as ManagerLastName
FROM Employees
    LEFT JOIN Employees AS Manager ON
        Employees.ReportsTo = Manager.EmployeeID

Po aktualizaci SELECT příkazu uložte změny tak, že přejdete do nabídky Soubor a zvolíte Uložit Employees_Select. Případně můžete kliknout na ikonu Uložit na panelu nástrojů nebo stisknout Kombinaci kláves Ctrl+S. Po uložení změn klikněte pravým tlačítkem myši na uloženou proceduru Employees_Select v Průzkumníku serveru a zvolte Spustit. Tím se spustí uložená procedura a zobrazí se její výsledky v okně Výstup (viz obrázek 9).

Výsledky uložených procedur se zobrazí v okně výstupu.

Obrázek 9: Výsledky uložených procedur se zobrazují v okně výstupu (kliknutím zobrazíte obrázek s plnou velikostí).

Krok 3: Aktualizace sloupců datové tabulky

V tomto okamžiku uložená procedura Employees_Select vrací ManagerFirstName a ManagerLastName hodnoty, ale EmployeesDataTable chybí tyto sloupce. Tyto chybějící sloupce lze do tabulky DataTable přidat jedním ze dvou způsobů:

  • Ručně – klikněte pravým tlačítkem myši na tabulku DataTable v Návrháři datové sady a v nabídce Přidat zvolte Sloupec. Sloupec pak můžete pojmenovat a odpovídajícím způsobem nastavit jeho vlastnosti.
  • Automaticky – Průvodce konfigurací objektu TableAdapter aktualizuje sloupce tabulky DataTable tak, aby odrážela pole vrácená uloženou procedurou SelectCommand . Při použití ad-hoc příkazů SQL průvodce také odebere InsertCommand, UpdateCommand a DeleteCommand vlastnosti, protože SelectCommand nyní obsahuje JOIN. Při použití uložených procedur však tyto vlastnosti příkazu zůstanou nedotčené.

V předchozích tutoriálech jsme prozkoumali ruční přidávání sloupců datové tabulky, včetně Hlavního/Detailního použití seznamu hlavních záznamů s odrážkami s detailem DataList a Nahrávání souborů, a v našem dalším tutoriálu se na tento proces podíváme podrobněji. Pro účely tohoto kurzu však použijeme automatický přístup prostřednictvím průvodce konfigurací TableAdapter.

Začněte tak, že kliknete pravým tlačítkem na EmployeesTableAdapter ikonu a v místní nabídce vyberete Konfigurovat. Zobrazí se průvodce konfigurací TableAdapter, který obsahuje seznam uložených procedur používaných k výběru, vkládání, aktualizaci a odstraňování společně s vrácenými hodnotami a parametry (pokud existuje). Obrázek 10 ukazuje průvodce. Vidíme, že uložená Employees_Select procedura teď vrací ManagerFirstName pole a ManagerLastName pole.

Průvodce zobrazí aktualizovaný seznam sloupců pro uloženou proceduru Employees_Select.

Obrázek 10: Průvodce zobrazuje aktualizovaný seznam sloupců uložené Employees_Select procedury (kliknutím zobrazíte obrázek v plné velikosti).

Dokončete průvodce kliknutím na Dokončit. Po návratu do Návrháře datové sady EmployeesDataTable obsahuje dva další sloupce: ManagerFirstName a ManagerLastName.

Tabulka EmployeesDataTable obsahuje dva nové sloupce.

Obrázek 11: EmployeesDataTable Obsahuje dva nové sloupce (kliknutím zobrazíte obrázek s plnou velikostí)

Abychom si ukázali, že aktualizovaná Employees_Select uložená procedura je platná a že možnosti vložení, aktualizace a odstranění objektu TableAdapter jsou stále funkční, vytvoříme webovou stránku, která uživatelům umožňuje zobrazit a odstranit zaměstnance. Než ale vytvoříme takovou stránku, musíme nejprve vytvořit novou třídu ve vrstvě obchodní logiky pro práci se zaměstnanci z datové sady NorthwindWithSprocs . V kroku 4 vytvoříme EmployeesBLLWithSprocs třídu. V kroku 5 použijeme tuto třídu z ASP.NET stránky.

Krok 4: Implementace vrstvy obchodní logiky

Ve složce s názvem EmployeesBLLWithSprocs.csvytvořte nový soubor ~/App_Code/BLL třídy . Tato třída napodobuje sémantiku existující EmployeesBLL třídy, pouze tato nová poskytuje méně metod a používá NorthwindWithSprocs DataSet (místo Northwind DataSet). Do třídy přidejte následující kód EmployeesBLLWithSprocs .

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using NorthwindWithSprocsTableAdapters;
[System.ComponentModel.DataObject]
public class EmployeesBLLWithSprocs
{
    private EmployeesTableAdapter _employeesAdapter = null;
    protected EmployeesTableAdapter Adapter
    {
        get
        {
            if (_employeesAdapter == null)
                _employeesAdapter = new EmployeesTableAdapter();
            return _employeesAdapter;
        }
    }
    [System.ComponentModel.DataObjectMethodAttribute
        (System.ComponentModel.DataObjectMethodType.Select, true)]
    public NorthwindWithSprocs.EmployeesDataTable GetEmployees()
    {
        return Adapter.GetEmployees();
    }
    [System.ComponentModel.DataObjectMethodAttribute
        (System.ComponentModel.DataObjectMethodType.Delete, true)]
    public bool DeleteEmployee(int employeeID)
    {
        int rowsAffected = Adapter.Delete(employeeID);
        // Return true if precisely one row was deleted, otherwise false
        return rowsAffected == 1;
    }
}

Vlastnost Adapter třídy EmployeesBLLWithSprocs vrátí instanci NorthwindWithSprocs DataSetu EmployeesTableAdapter. Používá se ve třídě s GetEmployees a DeleteEmployee metodami. Metoda GetEmployees volá odpovídající GetEmployees metoduEmployeesTableAdapter, která vyvolá uloženou proceduru Employees_Select a naplní její výsledky v objektu EmployeeDataTable. Metoda DeleteEmployee podobně volá metodu EmployeesTableAdapter s Delete , která vyvolá uloženou proceduru Employees_Delete .

Krok 5: Práce s daty ve vrstvě prezentace

Po dokončení předmětu EmployeesBLLWithSprocs jsme připraveni pracovat s daty zaměstnanců prostřednictvím ASP.NET stránky. JOINs.aspx Otevřete stránku ve AdvancedDAL složce a přetáhněte Objekt GridView z panelu nástrojů do Návrháře a nastavte jeho ID vlastnost na Employees. Poté ze smart tagu GridView připojte mřížku k novému ovládacímu prvku ObjectDataSource s názvem EmployeesDataSource.

Nakonfigurujte ObjectDataSource tak, aby používal třídu EmployeesBLLWithSprocs, a na kartách SELECT a DELETE se ujistěte, že jsou metody GetEmployees a DeleteEmployee vybrány z rozevíracích seznamů. Kliknutím na tlačítko Dokončit dokončete konfiguraci ObjectDataSource.

Konfigurujte ObjectDataSource pro použití třídy EmployeesBLLWithSprocs

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

Nechte ObjectDataSource použít metody GetEmployees a DeleteEmployee

Obrázek 13: Použijte ObjectDataSource pomocí GetEmployees a DeleteEmployee metod (kliknutím zobrazíte obrázek s plnou velikostí)

Visual Studio do objektu GridView přidá BoundField pro každý z sloupců EmployeesDataTable. Odeberte všechny tyto objekty BoundField s výjimkou Title, LastName, FirstName, ManagerFirstName, a ManagerLastName, a přejmenujte vlastnosti posledních čtyř BoundFields na příjmení, jméno, křestní jméno manažera a příjmení manažera, v uvedeném pořadí.

Abychom uživatelům umožnili odstranit zaměstnance z této stránky, musíme udělat dvě věci. Nejprve nastavte GridView tak, aby poskytovalo možnosti odstranění zaškrtnutím volby Povolit odstranění v její inteligentní značce. Za druhé změňte vlastnost ObjectDataSource OldValuesParameterFormatString z hodnoty nastavené průvodcem ObjectDataSource (original_{0}) na výchozí hodnotu ({0}). Po provedení těchto změn by deklarativní kód GridView a ObjectDataSource měly vypadat přibližně takto:

<asp:GridView ID="Employees" runat="server" AutoGenerateColumns="False" 
    DataKeyNames="EmployeeID" DataSourceID="EmployeesDataSource">
    <Columns>
        <asp:CommandField ShowDeleteButton="True" />
        <asp:BoundField DataField="Title" 
            HeaderText="Title" 
            SortExpression="Title" />
        <asp:BoundField DataField="LastName" 
            HeaderText="Last Name" 
            SortExpression="LastName" />
        <asp:BoundField DataField="FirstName" 
            HeaderText="First Name" 
            SortExpression="FirstName" />
        <asp:BoundField DataField="ManagerFirstName" 
            HeaderText="Manager's First Name" 
            SortExpression="ManagerFirstName" />
        <asp:BoundField DataField="ManagerLastName" 
            HeaderText="Manager's Last Name" 
            SortExpression="ManagerLastName" />
    </Columns>
</asp:GridView>
<asp:ObjectDataSource ID="EmployeesDataSource" runat="server" 
    DeleteMethod="DeleteEmployee" OldValuesParameterFormatString="{0}" 
    SelectMethod="GetEmployees" TypeName="EmployeesBLLWithSprocs">
    <DeleteParameters>
        <asp:Parameter Name="employeeID" Type="Int32" />
    </DeleteParameters>
</asp:ObjectDataSource>

Otestujte stránku tak, že ji navštívíte v prohlížeči. Jak ukazuje obrázek 14, stránka zobrazí seznam všech zaměstnanců a jména jejich nadřízených (za předpokladu, že ho mají).

Spojení (JOIN) v uložené proceduře Employees_Select vrátí jméno manažera.

Obrázek 14: Uložená procedura JOINEmployees_Select vrátí název správce (kliknutím zobrazíte obrázek v plné velikosti).

Kliknutím na tlačítko Odstranit spustíte pracovní postup odstraňování, který vyvrcholí při provádění Employees_Delete uložené procedury. Pokus o DELETE příkaz v uložené proceduře se však nezdaří kvůli porušení omezení cizího klíče (viz obrázek 15). Konkrétně každý zaměstnanec má v Orders tabulce jeden nebo více záznamů, což způsobí neúspěch smazání.

Odstranění zaměstnance, který má odpovídající objednávky, způsobí porušení omezení cizího klíče.

Obrázek 15: Odstranění zaměstnance, který má odpovídající objednávky, způsobí porušení omezení cizího klíče (kliknutím zobrazíte obrázek s plnou velikostí)

Pokud chcete umožnit odstranění zaměstnance, můžete:

  • Aktualizujte omezení cizího klíče tak, aby se mazání provádělo kaskádově.
  • Ručně odstraňte záznamy z Orders tabulky pro zaměstnance, které chcete odstranit, nebo
  • Před odstraněním Employees záznamu Orders aktualizujte uloženou Employees_Delete proceduru tak, aby nejprve odstranila související záznamy z tabulky. Tuto techniku jsme probrali v kurzu Použití existujících uložených procedur pro typed DataSet s TableAdapter .

Nechávám to jako úkol pro čtenáře.

Shrnutí

Při práci s relačními databázemi je běžné, že dotazy přetahují data z více souvisejících tabulek. Korelované poddotazy a JOIN poskytují dvě různé techniky pro přístup k datům ze souvisejících tabulek v dotazu. V předchozích kurzech jsme nejčastěji používali korelované poddotazy, protože TableAdapter nemůže automaticky generovat INSERT, UPDATEa DELETE příkazy pro dotazy zahrnující JOIN s. I když je možné tyto hodnoty zadat ručně, při použití ad hoc příkazů SQL se při dokončení průvodce konfigurací TableAdapter přepíší všechna přizpůsobení.

Objekty TableAdapter vytvořené pomocí uložených procedur naštěstí netrpí stejnou křehkostí jako ty, které se vytvářejí pomocí ad hoc SQL příkazů. Proto je možné vytvořit Objekt TableAdapter, jehož hlavní dotaz používá JOIN při použití uložených procedur. V tomto kurzu jsme viděli, jak vytvořit takový TableAdapter. Začali jsme použitím dotazu bez JOIN a SELECT pro hlavní dotaz TableAdapteru, aby se automaticky vytvořily odpovídající uložené procedury pro vložení, aktualizaci a odstranění. Po dokončení počáteční konfigurace TableAdapter jsme rozšířili SelectCommand uloženou proceduru tak, aby používala JOIN, a znovu jsme spustili Průvodce konfigurací pro TableAdapter k aktualizaci EmployeesDataTable sloupců.

Opětovné spuštění Průvodce konfigurací TableAdapter automaticky aktualizovalo EmployeesDataTable sloupce tak, aby odrážely datová pole vrácená uloženou procedurou Employees_Select. Případně bychom tyto sloupce mohli do tabulky DataTable přidat ručně. V dalším kurzu prozkoumáme ruční přidávání sloupců do tabulky DataTable.

Šťastné programování!

O autorovi

Scott Mitchell, autor sedmi knih ASP/ASP.NET a zakladatel 4GuysFromRolla.com, pracuje s webovými technologiemi Microsoftu od roku 1998. Scott pracuje jako nezávislý konzultant, trenér a spisovatel. Jeho nejnovější kniha je Sams: Nauč se ASP.NET 2.0 za 24 hodin. Může být dosažitelný na mitchell@4GuysFromRolla.comadrese .

Zvláštní díky

Tato série kurzů byla zkontrolována mnoha užitečnými recenzenty. Vedoucí hodnotící tohoto kurzu byli Hilton Geisenow, David Suru a Teresa Murphy. Chcete si projít nadcházející články MSDN? Pokud ano, napište mi zprávu na mitchell@4GuysFromRolla.com.