Sdílet prostřednictvím


Ovládací prvky zdroje dat

od Microsoftu

Ovládací prvek DataGrid v ASP.NET 1.x znamenal velké zlepšení přístupu k datům ve webových aplikacích. Nebylo to ale tak uživatelsky přívětivé, jak by mohlo být. Stále vyžadoval značné množství kódu, aby z něj bylo možné získat velmi užitečné funkce. Takový je model ve všech snahách o přístup k datům v 1.x.

Ovládací prvek DataGrid v ASP.NET 1.x znamenal velké zlepšení přístupu k datům ve webových aplikacích. Nebylo to ale tak uživatelsky přívětivé, jak by mohlo být. Stále vyžadoval značné množství kódu, aby z něj bylo možné získat velmi užitečné funkce. Takový je model ve všech snahách o přístup k datům v 1.x.

ASP.NET 2.0 to řeší částečně ovládacími prvky zdroje dat. Ovládací prvky zdroje dat v ASP.NET 2.0 poskytují vývojářům deklarativní model pro načítání dat, zobrazení dat a úpravy dat. Účelem ovládacích prvků zdroje dat je zajistit konzistentní reprezentaci dat ovládacím prvkům vázaných na data bez ohledu na zdroj těchto dat. Jádrem ovládacích prvků zdroje dat v ASP.NET 2.0 je abstraktní třída DataSourceControl. DataSourceControl Třída poskytuje základní implementaci rozhraní IDataSource a rozhraní IListSource, z nichž druhý umožňuje přiřadit ovládací prvek zdroje dat jako Zdroj dat ovládacího prvku vázaného na data (prostřednictvím nové vlastnosti DataSourceId popisované později) a vystavit data v něm jako seznam. Každý seznam dat z ovládacího prvku zdroje dat je vystaven jako DataSourceView objekt. Přístup k instancím DataSourceView poskytuje rozhraní IDataSource. Například GetViewNames Metoda vrátí ICollection, který umožňuje vytvořit výčet DataSourceViews přidružené k určitému ovládacímu prvku zdroje dat a GetView metoda umožňuje přístup k určitému DataSourceView instance podle názvu.

Ovládací prvky zdroje dat nemají žádné uživatelské rozhraní. Jsou implementovány jako serverové ovládací prvky, aby mohly podporovat deklarativní syntaxi a aby v případě potřeby měly přístup ke stavu stránky. Ovládací prvky zdroje dat nevykreslují klientovi žádné značky HTML.

Poznámka

Jak uvidíte později, ukládání do mezipaměti přináší také výhody, které přináší použití ovládacích prvků zdroje dat.

Ukládání připojovacích řetězců

Než se pustíme do konfigurace ovládacích prvků zdroje dat, měli bychom probrat novou funkci v ASP.NET 2.0 týkající se připojovacích řetězců. ASP.NET 2.0 zavádí do konfiguračního souboru novou část, která umožňuje snadno ukládat připojovací řetězce, které se dají dynamicky číst za běhu. Oddíl <connectionStrings> usnadňuje ukládání připojovacích řetězců.

Následující fragment kódu přidá nový připojovací řetězec.

<connectionStrings> <add name="Northwind" connectionString="Data Source=localhost; Integrated Security=SSPI;Initial Catalog=Northwind;" providerName="System.Data.SqlClient" /> </connectionStrings>

Poznámka

Stejně jako v případě oddílu appSettings> se <část connectionStrings> zobrazí v konfiguračním souboru mimo <oddíl system.web><.

Chcete-li použít tento připojovací řetězec, můžete při nastavování atributu ConnectionString serverového ovládacího prvku použít následující syntaxi.

ConnectionString="<%$ ConnectionStrings:Northwind%>"

Část <connectionStrings> je také možné zašifrovat, aby nebyly zpřístupněny citlivé informace. Této schopnosti se budeme zabývat v pozdějším modulu.

Ukládání zdrojů dat do mezipaměti

Každý DataSourceControl poskytuje čtyři vlastnosti pro konfiguraci ukládání do mezipaměti; EnableCaching, CacheDuration, CacheExpirationPolicy a CacheKeyDependency.

Enablecaching

EnableCaching je logická vlastnost, která určuje, jestli je pro ovládací prvek zdroje dat povolené ukládání do mezipaměti.

CacheDuration – vlastnost

CacheDuration Vlastnost nastaví počet sekund, po který mezipaměť zůstane platná. Nastavení této vlastnosti na hodnotu 0 způsobí, že mezipaměť zůstane platná, dokud se explicitně neaktivuje.

CacheExpirationPolicy – vlastnost

Vlastnost CacheExpirationPolicy lze nastavit na absolutní nebo sliding. Nastavení na Absolutní znamená, že maximální doba, po kterou budou data uložena v mezipaměti, je počet sekund určený vlastností CacheDuration. Když ho nastavíte na posuvné, čas vypršení platnosti se při provedení každé operace resetuje.

CacheKeyDependency – vlastnost

Pokud je pro vlastnost CacheKeyDependency zadána řetězcová hodnota, ASP.NET na základě daného řetězce nastaví novou závislost mezipaměti. To vám umožní explicitně zneplatnit mezipaměť jednoduše změnou nebo odebráním CacheKeyDependency.

Důležité: Pokud je povolené zosobnění a přístup ke zdroji dat nebo obsahu dat je založený na identitě klienta, doporučujeme zakázat ukládání do mezipaměti nastavením EnableCaching na False. Pokud je v tomto scénáři povolené ukládání do mezipaměti a jiný uživatel než uživatel, který původně požádal o data, vydá žádost, autorizace pro zdroj dat se nevynutí. Data se budou jednoduše obsluhovat z mezipaměti.

Ovládací prvek SqlDataSource

Ovládací prvek SqlDataSource umožňuje vývojáři přistupovat k datům uloženým v jakékoli relační databázi, která podporuje ADO.NET. Může použít zprostředkovatele System.Data.SqlClient pro přístup k databázi SQL Server, zprostředkovateli System.Data.OleDb, zprostředkovateli System.Data.Odbc nebo zprostředkovateli System.Data.OracleClient pro přístup k Oracle. SqlDataSource se proto určitě nepoužívá pouze pro přístup k datům v databázi SQL Server.

Pokud chcete použít SqlDataSource, stačí zadat hodnotu vlastnosti ConnectionString a zadat příkaz SQL nebo uloženou proceduru. Ovládací prvek SqlDataSource se postará o práci se základní architekturou ADO.NET. Otevře připojení, dotáže se zdroje dat nebo spustí uloženou proceduru, vrátí data a pak připojení za vás zavře.

Poznámka

Vzhledem k tomu, DataSourceControl třída automaticky ukončí připojení za vás, měla by snížit počet volání zákazníka generovaných únikem databázová připojení.

Následující fragment kódu vytvoří vazbu ovládacího prvku DropDownList na ovládací prvek SqlDataSource pomocí připojovacího řetězce uloženého v konfiguračním souboru, jak je znázorněno výše.

<asp:SqlDataSource id="SqlDataSource1" runat="server" DataSourceMode="DataReader" ConnectionString="<%$ ConnectionStrings:Northwind%>" SelectCommand="SELECT EmployeeID, LastName FROM Employees"> </asp:SqlDataSource><asp:DropDownList id="ListBox1" runat="server" DataTextField="LastName" DataValueField="EmployeeID" DataSourceID="SqlDataSource1"> </asp:DropDownList>

Jak je znázorněno výše, vlastnost DataSourceMode sqlDataSource určuje režim pro zdroj dat. Ve výše uvedeném příkladu je vlastnost DataSourceMode nastavená na DataReader. V takovém případě SqlDataSource vrátí IDataReader objekt pomocí kurzoru jen dopředný a jen pro čtení. Zadaný typ vráceného objektu je řízen poskytovatelem, který se používá. V tomto případě používám zprostředkovatele System.Data.SqlClient, jak je uvedeno v <části connectionStrings> web.config souboru. Proto vrácený objekt bude typu SqlDataReader. Zadáním hodnoty DataSourceMode dataSet mohou být data uložena v datové sadě na serveru. Tento režim umožňuje přidávat funkce, jako je řazení, stránkování atd. Kdybych byl data-vazbu SqlDataSource na GridView ovládací prvek, bych zvolil režim DataSet. V případě rozevíracího seznamu je však režim DataReader správnou volbou.

Poznámka

Při ukládání SqlDataSource do mezipaměti nebo AccessDataSource musí být vlastnost DataSourceMode nastavena na DataSet. K výjimce dojde, pokud povolíte ukládání do mezipaměti s DataSourceMode DataReader.

SqlDataSource – vlastnosti

Níže jsou uvedeny některé vlastnosti ovládacího prvku SqlDataSource.

CancelSelectOnNullParameter

Logická hodnota, která určuje, zda je příkaz select zrušen, pokud má jeden z parametrů hodnotu null. Ve výchozím nastavení je true.

Conflictdetection

V situaci, kdy více uživatelů aktualizovat zdroj dat ve stejnou dobu, ConflictDetection vlastnost určuje chování SqlDataSource ovládacího prvku. Tato vlastnost se vyhodnotí na jednu z hodnot výčtu ConflictOptions. Tyto hodnoty jsou CompareAllValues a OverwriteChanges. Pokud je nastavena hodnota OverwriteChanges, poslední osoba, která zapíše data do zdroje dat, přepíše všechny předchozí změny. Pokud je však ConflictDetection vlastnost nastavena na CompareAllValues, vytvoří se parametry pro sloupce vrácené SelectCommand a parametry jsou vytvořeny také pro uložení původních hodnot v každém z těchto sloupců, což umožňuje SqlDataSource určit, zda se hodnoty změnily od selectCommand byl proveden.

Deletecommand

Nastaví nebo získá řetězec SQL použitý při odstraňování řádků z databáze. Může to být buď dotaz SQL, nebo název uložené procedury.

DeleteCommandType

Nastaví nebo získá typ příkazu delete, dotaz SQL (Text) nebo uloženou proceduru (StoredProcedure).

Deleteparameters

Vrátí parametry, které jsou používány DeleteCommand objektu SqlDataSourceView přidružené k SqlDataSource ovládací prvek.

Oldvaluesparameterformatstring

Tato vlastnost se používá k určení formátu parametrů původní hodnoty v případech, kdy ConflictDetection vlastnost je nastavena na CompareAllValues. Výchozí hodnota znamená {0} , že parametry původní hodnoty budou mít stejný název jako původní parametr. Jinými slovy, pokud je název pole EmployeeID, původní parametr hodnoty by byl @EmployeeID.

Selectcommand

Nastaví nebo získá řetězec SQL, který se používá k načtení dat z databáze. Může to být dotaz SQL nebo název uložené procedury.

SelectCommandType

Nastaví nebo získá typ příkazu select, buď dotaz SQL (Text), nebo uloženou proceduru (StoredProcedure).

Selectparameters

Vrátí parametry, které jsou používány SelectCommand objektu SqlDataSourceView přidružené k Ovládací prvek SqlDataSource.

Sortparametername

Získá nebo nastaví název parametru uložené procedury, který se používá při řazení dat načtených ovládacím prvku zdroje dat. Platí pouze v případech, kdy je vlastnost SelectCommandType nastavená na Hodnotu StoredProcedure.

Sqlcachedependency

Řetězec oddělený středníkem, který určuje databáze a tabulky používané v závislosti SQL Server mezipaměti. (Závislosti mezipaměti SQL budou popsány v pozdějším modulu.)

Updatecommand

Nastaví nebo získá řetězec SQL, který se používá při aktualizaci dat v databázi. Může to být dotaz SQL nebo název uložené procedury.

UpdateCommandType

Nastaví nebo získá typ příkazu update, buď dotaz SQL (Text), nebo uloženou proceduru (StoredProcedure).

Updateparameters

Vrátí parametry, které jsou používány UpdateCommand objektu SqlDataSourceView přidružené k SqlDataSource ovládací prvek.

Ovládací prvek AccessDataSource

Ovládací prvek AccessDataSource je odvozen z třídy SqlDataSource a slouží k vytvoření vazby dat k databázi Aplikace Microsoft Access. Vlastnost ConnectionString ovládacího prvku AccessDataSource je vlastnost jen pro čtení. Místo použití vlastnosti ConnectionString se vlastnost DataFile používá k odkazování na databázi Aplikace Access, jak je znázorněno níže.

<asp:AccessDataSource id="AccessDataSource1" runat="server" DataFile="~/App_Data/Northwind.mdb"> </asp:AccessDataSource>

AccessDataSource vždy nastaví Název zprostředkovatele základního zdroje SqlDataSource na System.Data.OleDb a připojí se k databázi pomocí zprostředkovatele Microsoft.Jet.OLEDB.4.0 OLE DB. Nelze použít ovládací prvek AccessDataSource pro připojení k databázi aplikace Access chráněné heslem. Pokud se potřebujete připojit k databázi chráněné heslem, měli byste použít ovládací prvek SqlDataSource.

Poznámka

Databáze aplikace Access uložené na webu by měly být umístěny v adresáři App_Data. ASP.NET nepovoluje procházení souborů v tomto adresáři. Pokud používáte accessové databáze, musíte účtu procesu udělit oprávnění ke čtení a zápisu do adresáře App_Data.

Ovládací prvek XmlDataSource

XmlDataSource slouží k vytvoření vazby dat XML na ovládací prvky vázané na data. K souboru XML můžete vytvořit vazbu pomocí vlastnosti DataFile nebo můžete vytvořit vazbu na řetězec XML pomocí vlastnosti Data. XmlDataSource zveřejňuje atributy XML jako svázatelná pole. V případech, kdy potřebujete vytvořit vazbu na hodnoty, které nejsou reprezentovány jako atributy, budete muset použít transformaci XSL. K filtrování dat XML můžete použít také výrazy XPath.

Představte si následující soubor XML:

<?xml version="1.0" encoding="utf-8" ?> <People> <Person FirstName="Jake" LastName="Stone"> <Address> <Street>345 Maple St.</Street> <City>Redmond</City> <Region>WA</Region> <ZipCode>01434</ZipCode> </Address> <Job> <Title>CEO</Title> <Description>Develops company strategies.</Description> </Job> </Person> <Person FirstName="Jacob" LastName="Ladder"> <Address> <Street>123 Elm St.</Street> <City>Seattle</City> <Region>WA</Region> <ZipCode>11223</ZipCode> </Address> <Job> <Title>Attorney</Title> <Description>Reviews legal issues.</Description> </Job> </Person> <Person FirstName="Angela" LastName="Hound"> <Address> <Street>34 Palm Avenue</Street> <City>Renton</City> <Region>WA</Region> <ZipCode>63910</ZipCode> </Address> <Job> <Title>IT Director</Title> <Description>In charge of corporate network.</Description> </Job> </Person> </People>

Všimněte si, že XmlDataSource používá XPath vlastnost Lidé/Person k filtrování pouze <na uzly Person>. DropDownList pak data-vazby na LastName atribut pomocí DataTextField vlastnost.

Zatímco XmlDataSource ovládací prvek se primárně používá k vytvoření vazby dat s daty XML jen pro čtení, je možné upravit datový soubor XML. Všimněte si, že v takových případech se automatické vkládání, aktualizace a odstraňování informací v souboru XML neprovádí automaticky jako u jiných ovládacích prvků zdroje dat. Místo toho budete muset napsat kód pro ruční úpravu dat pomocí následujících metod ovládacího prvku XmlDataSource.

GetXmlDocument

Načte XmlDocument objekt obsahující kód XML načtený XmlDataSource.

Uložit

Uloží XmlDocument v paměti zpět do zdroje dat.

Je důležité si uvědomit, že metoda Save bude fungovat pouze při splnění následujících dvou podmínek:

  1. XmlDataSource používá vlastnost DataFile k vytvoření vazby se souborem XML místo vlastnosti Data pro vytvoření vazby na data XML v paměti.
  2. Prostřednictvím vlastnosti Transform nebo TransformFile není zadána žádná transformace.

Všimněte si také, že Save metoda může získat neočekávané výsledky při souběžné zavolání více uživatelů.

Ovládací prvek ObjectDataSource

Ovládací prvky zdroje dat, které jsme až do této chvíle probírali, jsou vynikající volbou pro dvouvrstvé aplikace, kde řízení zdroje dat komunikuje přímo s úložištěm dat. Mnoho reálných aplikací jsou ale vícevrstvé aplikace, u kterých může řízení zdroje dat potřebovat komunikovat s obchodním objektem, který zase komunikuje s datovou vrstvou. V těchto situacích ObjectDataSource vyplní účet pěkně. ObjectDataSource funguje ve spojení se zdrojovým objektem. Ovládací prvek ObjectDataSource vytvoří instanci zdrojového objektu, zavolá zadanou metodu a odstraní instanci objektu v rámci jednoho požadavku, pokud objekt obsahuje metody instance místo statických metod (Sdílené v jazyce Visual Basic). Proto musí být objekt bezstavového stavu. To znamená, že objekt by měl získat a uvolnit všechny požadované prostředky v rámci jednoho požadavku. Můžete řídit způsob vytvoření zdrojového objektu zpracováním ObjectCreating události ObjectDataSource ovládacího prvku ObjectDataSource. Můžete vytvořit instanci zdrojového objektu a pak nastavit ObjectInstance vlastnost ObjectDataSourceEventArgs třídy na tuto instanci. ObjectDataSource Ovládací prvek bude používat instanci, která je vytvořena v ObjectCreating události místo vytvoření instance samostatně.

Pokud zdrojový objekt pro ObjectDataSource ovládací prvek zpřístupňuje veřejné statické metody (Sdílené v jazyce Visual Basic), které lze volat pro načtení a úpravu dat, ObjectDataSource ovládací prvek bude volat tyto metody přímo. Pokud ObjectDataSource ovládací prvek musí vytvořit instanci zdrojového objektu, aby bylo možné provádět volání metody, musí objekt obsahovat veřejný konstruktor, který nepřijímá žádné parametry. ObjectDataSource Ovládací prvek bude volat tento konstruktor při vytvoření nové instance zdrojového objektu.

Pokud zdrojový objekt neobsahuje veřejný konstruktor bez parametrů, můžete vytvořit instanci zdrojového objektu, který bude použit ObjectDataSource ovládací prvek v ObjectCreating události.

Určení metod objektů

Zdrojový objekt ovládacího prvku ObjectDataSource může obsahovat libovolný počet metod, které se používají k výběru, vložení, aktualizaci nebo odstranění dat. Tyto metody jsou volány ObjectDataSource ovládací prvek na základě názvu metody, jak je identifikováno buď pomocí SelectMethod, InsertMethod, UpdateMethod, nebo DeleteMethod ObjectDataSource vlastnost ovládacího prvku ObjectDataSource. Zdrojový objekt může také obsahovat volitelnou SelectCount metodu, která je identifikována ObjectDataSource ovládací prvek pomocí SelectCountMethod vlastnost, která vrací počet celkového počtu objektů ve zdroji dat. Ovládací prvek ObjectDataSource zavolá metodu SelectCount po volání metody Select k načtení celkového počtu záznamů ve zdroji dat pro použití při stránkování.

Testovací prostředí s využitím ovládacích prvků zdroje dat

Cvičení 1 – zobrazení dat pomocí ovládacího prvku SqlDataSource

Následující cvičení používá ovládací prvek SqlDataSource pro připojení k databázi Northwind. Předpokládá, že máte přístup k databázi Northwind v instanci SQL Server 2000.

  1. Vytvořte nový web ASP.NET.

  2. Přidejte nový soubor web.config.

    1. Klikněte pravým tlačítkem na projekt v Průzkumník řešení a klikněte na Přidat novou položku.
    2. V seznamu šablon zvolte Konfigurační soubor webu a klikněte na Přidat.
  3. <Upravte část connectionStrings> následujícím způsobem:

    <asp:SqlDataSource ID="SqlDataSource1" runat="server"
        ConnectionString="<%$ConnectionStrings:Northwind%>"
        SelectCommand="SELECT * FROM Products">
    </asp:SqlDataSource>
    
  4. Přepněte do zobrazení kódu a přidejte atribut ConnectionString a Atribut SelectCommand do <ovládacího prvku asp:SqlDataSource> následujícím způsobem:

    <asp:SqlDataSource ID="SqlDataSource1" runat="server"
        ConnectionString="<%$ConnectionStrings:Northwind%>"
        SelectCommand="SELECT * FROM Products">
    </asp:SqlDataSource>
    
  5. V návrhovém zobrazení přidejte nový ovládací prvek GridView.

  6. V rozevíracím seznamu Zvolit zdroj dat v nabídce Úkoly GridView zvolte SqlDataSource1.

  7. Klikněte pravým tlačítkem na Default.aspx a v nabídce zvolte Zobrazit v prohlížeči. Po zobrazení výzvy k uložení klikněte na Ano.

  8. GridView zobrazí data z tabulky Products.

Cvičení 2 – úprava dat pomocí ovládacího prvku SqlDataSource

Následující cvičení ukazuje, jak vytvořit vazbu dat ovládacího prvku DropDownList pomocí deklarativní syntaxe a umožňuje upravit data prezentovaná v ovládacím prvku DropDownList.

  1. V návrhovém zobrazení odstraňte ovládací prvek GridView z default.aspx.

    Důležité: Ponechte na stránce ovládací prvek SqlDataSource.

  2. Přidejte ovládací prvek DropDownList do souboru Default.aspx.

  3. Přepněte do zobrazení Zdroj.

  4. Přidejte atribut DataSourceId, DataTextField a DataValueField do <ovládacího prvku asp:DropDownList> následujícím způsobem:

    <asp:DropDownList ID="ddlProducts" runat="server"
         DataSourceId="SqlDataSource1" DataTextField="ProductName"
         DataValueField="ProductID">
    </asp:DropDownList>
    
  5. Uložte soubor Default.aspx a zobrazte ho v prohlížeči. Všimněte si, že dropDownList obsahuje všechny produkty z databáze Northwind.

  6. Zavřete prohlížeč.

  7. V zobrazení Source souboru Default.aspx přidejte nový ovládací prvek TextBox pod ovládací prvek DropDownList. Změňte vlastnost ID TextBox na txtProductName.

  8. Pod ovládací prvek TextBox přidejte nový ovládací prvek Tlačítko. Změňte vlastnost ID tlačítka na btnUpdate a vlastnost Text na Aktualizovat název produktu.

  9. V zobrazení Zdroj default.aspx přidejte vlastnost UpdateCommand a dvě nové UpdateParameters do značky SqlDataSource následujícím způsobem:

    <asp:SqlDataSource ID="SqlDataSource1" runat="server"
        ConnectionString="<%$ConnectionStrings:Northwind%>"
        SelectCommand="SELECT * FROM Products"
        UpdateCommand="UPDATE Products SET ProductName=@ProductName WHERE ProductID=@ProductID">
          <UpdateParameters>
          <asp:ControlParameter Name="ProductName" 
            ControlID="txtProductName" PropertyName="Text" />
          <asp:ControlParameter Name="ProductID" 
            ControlID="ddlProducts" PropertyName="SelectedValue" />
    </asp:SqlDataSource>
    

    Poznámka

    Všimněte si, že v tomto kódu jsou přidané dva parametry aktualizace (ProductName a ProductID). Tyto parametry jsou mapovány na text vlastnost txtProductName TextBox a SelectedValue vlastnost ddlProducts DropDownList.

  10. Přepněte do návrhového zobrazení a poklikáním na ovládací prvek Tlačítko přidejte obslužnou rutinu události.

  11. Do kódu btnUpdate_Click přidejte následující kód:

    SqlDataSource1.Update();
    
  12. Klikněte pravým tlačítkem na Default.aspx a zvolte, jestli se má zobrazit v prohlížeči. Po zobrazení výzvy k uložení všech změn klikněte na Ano.

  13. ASP.NET částečné třídy 2.0 umožňují kompilaci za běhu. Aby se změny kódu projevily, není nutné vytvářet aplikaci.

  14. Vyberte produkt z rozevíracího seznamu.

  15. Do textového pole zadejte nový název vybraného produktu a klikněte na tlačítko Aktualizovat.

  16. Název produktu se aktualizuje v databázi.

Cvičení 3 Použití ovládacího prvku ObjectDataSource

V tomto cvičení si ukážeme, jak používat ovládací prvek ObjectDataSource a zdrojový objekt k interakci s databází Northwind.

  1. Klikněte pravým tlačítkem na projekt v Průzkumník řešení a klikněte na Přidat novou položku.

  2. V seznamu šablon vyberte Webový formulář. Změňte název na object.aspx a klikněte na Přidat.

  3. Klikněte pravým tlačítkem na projekt v Průzkumník řešení a klikněte na Přidat novou položku.

  4. V seznamu šablon vyberte Třída. Změňte název třídy na NorthwindData.cs a klikněte na Přidat.

  5. Po zobrazení výzvy k přidání třídy do složky App_Code klikněte na Ano.

  6. Do souboru NorthwindData.cs přidejte následující kód:

    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 System.Data.SqlClient;
    public class NorthwindData {
        private string _connectionString;
        public NorthwindData() {
            Initialize();
        }
    
        private void Initialize() {
            if (ConfigurationManager.ConnectionStrings["Northwind"] == null ||
                ConfigurationManager.ConnectionStrings["Northwind"].ConnectionString.Trim() == "") {
                    throw new Exception("A connection string named 'Northwind' with " +
                    "a valid connection string must exist in the <connectionStrings> " +
                    "configuration section for the application.");
            }
            _connectionString = ConfigurationManager.ConnectionStrings["Northwind"].ConnectionString;
        }
    
        public DataTable GetAllEmployees(string sortColumns, int startRecord, int maxRecords) {
            VerifySortColumns(sortColumns);
            string sqlCmd = "SELECT EmployeeID, LastName, FirstName, Address, " +
                "City, Region, PostalCode FROM Employees ";
            if (sortColumns.Trim() == "")
                sqlCmd += "ORDER BY EmployeeID";
            else
                sqlCmd += "ORDER BY " + sortColumns;
    
            SqlConnection conn = new SqlConnection(_connectionString);
            SqlDataAdapter da = new SqlDataAdapter(sqlCmd, conn);
            DataSet ds = new DataSet();
            try {
                conn.Open();
                da.Fill(ds, startRecord, maxRecords, "Employees");
            } catch (SqlException e) {
                // Handle exception.
            } finally {
                conn.Close();
            }
            return ds.Tables["Employees"];
        }
    
        public int SelectCount() {
            SqlConnection conn = new SqlConnection(_connectionString);
            SqlCommand cmd = new SqlCommand("SELECT COUNT(*) FROM Employees", conn);
            int result = 0;
    
            try {
                conn.Open();
                result = (int)cmd.ExecuteScalar();
            } catch (SqlException e) {
                // Handle exception.
            } finally {
                conn.Close();
            }
            return result;
        }
    
        //////////
        // Verify that only valid columns are specified in the sort expression to
        // avoid a SQL Injection attack.
        private void VerifySortColumns(string sortColumns) {
            if (sortColumns.ToLowerInvariant().EndsWith(" desc"))
                sortColumns = sortColumns.Substring(0, sortColumns.Length - 5);
            string[] columnNames = sortColumns.Split(',');
            foreach (string columnName in columnNames) {
                switch (columnName.Trim().ToLowerInvariant()) {
                    case "employeeid":
                        break;
                    case "lastname":
                        break;
                    case "firstname":
                        break;
                    case "":
                        break;
                    default:
                        throw new ArgumentException("SortColumns contains an " +
                            "invalid column name.");
                        break;
                }
            }
        }
    
        // Select an employee.
        public DataTable GetEmployee(int EmployeeID) {
            SqlConnection conn = new SqlConnection(_connectionString);
            SqlDataAdapter da =
                new SqlDataAdapter("SELECT EmployeeID, LastName, FirstName, " +
                "Address, City, Region, PostalCode " +
                " FROM Employees WHERE EmployeeID = @EmployeeID", conn);
            da.SelectCommand.Parameters.Add("@EmployeeID", SqlDbType.Int).Value = EmployeeID;
            DataSet ds = new DataSet();
            try {
                conn.Open();
                da.Fill(ds, "Employees");
            } catch (SqlException e) {
                // Handle exception.
            } finally {
                conn.Close();
            }
    
            return ds.Tables["Employees"];
        }
    
        // Delete the Employee by ID.
        public int DeleteEmployee(int EmployeeID) {
             SqlConnection conn = new SqlConnection(_connectionString);
             SqlCommand cmd = new SqlCommand("DELETE FROM Employees WHERE " +
                 "EmployeeID = @EmployeeID", conn);
             cmd.Parameters.Add("@EmployeeID", SqlDbType.Int).Value = EmployeeID;
             int result = 0;
             try {
                 conn.Open();
                 result = cmd.ExecuteNonQuery();
             } catch (SqlException e) {
                 // Handle exception.
             } finally {
                 conn.Close();
             }
    
             return result;
         }
    
         // Update the Employee by original ID.
         public int UpdateEmployee(int EmployeeID, string LastName, string FirstName,
             string Address, string City, string Region,
             string PostalCode) {
             if (String.IsNullOrEmpty(FirstName))
                 throw new ArgumentException("FirstName cannot be null or an empty string.");
             if (String.IsNullOrEmpty(LastName))
                 throw new ArgumentException("LastName cannot be null or an empty string.");
             if (Address == null) { Address = String.Empty; }
             if (City == null) { City = String.Empty; }
             if (Region == null) { Region = String.Empty; }
             if (PostalCode == null) { PostalCode = String.Empty; }
    
             SqlConnection conn = new SqlConnection(_connectionString);
             SqlCommand cmd = new SqlCommand("UPDATE Employees " +
                 " SET FirstName=@FirstName, " +
                 "LastName=@LastName, " +
                 "Address=@Address, City=@City, " +
                 "Region=@Region, " +
                 "PostalCode=@PostalCode " +
                 "WHERE EmployeeID=@EmployeeID", conn);
             cmd.Parameters.Add("@FirstName", SqlDbType.VarChar, 10).Value = FirstName;
             cmd.Parameters.Add("@LastName", SqlDbType.VarChar, 20).Value = LastName;
             cmd.Parameters.Add("@Address", SqlDbType.VarChar, 60).Value = Address;
             cmd.Parameters.Add("@City", SqlDbType.VarChar, 15).Value = City;
             cmd.Parameters.Add("@Region", SqlDbType.VarChar, 15).Value = Region;
             cmd.Parameters.Add("@PostalCode", SqlDbType.VarChar, 10).Value = PostalCode;
             cmd.Parameters.Add("@EmployeeID", SqlDbType.Int).Value = EmployeeID;
    
             int result = 0;
             try {
                 conn.Open();
                 result = cmd.ExecuteNonQuery();
             } catch (SqlException e) {
                 // Handle exception.
             } finally {
                 conn.Close();
             }
    
             return result;
        }
    
        // Insert an Employee.
        public int InsertEmployee(string LastName, string FirstName,
            string Address, string City, string Region,
            string PostalCode) {
            if (String.IsNullOrEmpty(FirstName))
                throw new ArgumentException("FirstName cannot be null or an empty string.");
            if (String.IsNullOrEmpty(LastName))
                throw new ArgumentException("LastName cannot be null or an empty string.");
            if (Address == null) { Address = String.Empty; }
            if (City == null) { City = String.Empty; }
            if (Region == null) { Region = String.Empty; }
            if (PostalCode == null) { PostalCode = String.Empty; }
    
            SqlConnection conn = new SqlConnection(_connectionString);
            SqlCommand cmd = new SqlCommand("INSERT INTO Employees " +
                " (FirstName, LastName, Address, " +
                " City, Region, PostalCode) " +
                " Values(@FirstName, @LastName, " +
                "@Address, @City, @Region, @PostalCode); " +
                "SELECT @EmployeeID = SCOPE_IDENTITY()", conn);
    
            cmd.Parameters.Add("@FirstName", SqlDbType.VarChar, 10).Value = FirstName;
            cmd.Parameters.Add("@LastName", SqlDbType.VarChar, 20).Value = LastName;
            cmd.Parameters.Add("@Address", SqlDbType.VarChar, 60).Value = Address;
            cmd.Parameters.Add("@City", SqlDbType.VarChar, 15).Value = City;
            cmd.Parameters.Add("@Region", SqlDbType.VarChar, 15).Value = Region;
            cmd.Parameters.Add("@PostalCode", SqlDbType.VarChar, 10).Value = PostalCode;
            SqlParameter p = cmd.Parameters.Add("@EmployeeID", SqlDbType.Int);
                p.Direction = ParameterDirection.Output;
            int newEmployeeID = 0;
            try {
                conn.Open();
                cmd.ExecuteNonQuery();
                newEmployeeID = (int)p.Value;
            } catch (SqlException e) {
                // Handle exception.
            } finally {
                conn.Close();
            }
    
            return newEmployeeID;
        }
    
        //
        // Methods that support Optimistic Concurrency checks.
        //
        // Delete the Employee by ID.
        public int DeleteEmployee(int original_EmployeeID, string original_LastName,
            string original_FirstName, string original_Address,
            string original_City, string original_Region,
            string original_PostalCode) {
    
            if (String.IsNullOrEmpty(original_FirstName))
                throw new ArgumentException("FirstName cannot be null or an empty string.");
            if (String.IsNullOrEmpty(original_LastName))
                throw new ArgumentException("LastName cannot be null or an empty string.");
            if (original_Address == null) { original_Address = String.Empty; }
            if (original_City == null) { original_City = String.Empty; }
            if (original_Region == null) { original_Region = String.Empty; }
            if (original_PostalCode == null) { original_PostalCode = String.Empty; }
            string sqlCmd = "DELETE FROM Employees WHERE EmployeeID = " + @original_EmployeeID
    
            SqlConnection conn = new SqlConnection(_connectionString);
            SqlCommand cmd = new SqlCommand(sqlCmd, conn);
            cmd.Parameters.Add("@original_EmployeeID",
                SqlDbType.Int).Value = original_EmployeeID;
            cmd.Parameters.Add("@original_FirstName",
                SqlDbType.VarChar, 10).Value = original_FirstName;
            cmd.Parameters.Add("@original_LastName",
                SqlDbType.VarChar, 20).Value = original_LastName;
            cmd.Parameters.Add("@original_Address",
                SqlDbType.VarChar, 60).Value = original_Address;
            cmd.Parameters.Add("@original_City",
                SqlDbType.VarChar, 15).Value = original_City;
            cmd.Parameters.Add("@original_Region",
                SqlDbType.VarChar, 15).Value = original_Region;
            cmd.Parameters.Add("@original_PostalCode",
                SqlDbType.VarChar, 10).Value = original_PostalCode;
    
            int result = 0;
            try {
                conn.Open();
                result = cmd.ExecuteNonQuery();
            } catch (SqlException e) {
                // Handle exception.
            } finally {
                conn.Close();
            }
    
            return result;
        }
    
        // Update the Employee by original ID.
        public int UpdateEmployee(string LastName, string FirstName,
            string Address, string City, string Region,
            string PostalCode, int original_EmployeeID,
            string original_LastName, string original_FirstName,
            string original_Address, string original_City,
            string original_Region, string original_PostalCode) {
    
            if (String.IsNullOrEmpty(FirstName))
                throw new ArgumentException("FirstName cannot be null or an empty string.");
            if (String.IsNullOrEmpty(LastName))
                throw new ArgumentException("LastName cannot be null or an empty string.");
            if (Address == null) { Address = String.Empty; }
            if (City == null) { City = String.Empty; }
            if (Region == null) { Region = String.Empty; }
            if (PostalCode == null) { PostalCode = String.Empty; }
            if (original_Address == null) { original_Address = String.Empty; }
            if (original_City == null) { original_City = String.Empty; }
            if (original_Region == null) { original_Region = String.Empty; }
            if (original_PostalCode == null) { original_PostalCode = String.Empty; }
    
            string sqlCmd = "UPDATE Employees " +
                " SET FirstName = @FirstName, LastName = @LastName, " +
                " Address = @Address, City = @City, Region = @Region, " +
                " PostalCode = @PostalCode " +
                " WHERE EmployeeID = @original_EmployeeID";
    
            SqlConnection conn = new SqlConnection(_connectionString);
            SqlCommand cmd = new SqlCommand(sqlCmd, conn);
            cmd.Parameters.Add("@FirstName", SqlDbType.VarChar, 10).Value = FirstName;
            cmd.Parameters.Add("@LastName", SqlDbType.VarChar, 20).Value = LastName;
            cmd.Parameters.Add("@Address", SqlDbType.VarChar, 60).Value = Address;
            cmd.Parameters.Add("@City", SqlDbType.VarChar, 15).Value = City;
            cmd.Parameters.Add("@Region", SqlDbType.VarChar, 15).Value = Region;
            cmd.Parameters.Add("@PostalCode", SqlDbType.VarChar, 10).Value = PostalCode;
            cmd.Parameters.Add("@original_EmployeeID",
                SqlDbType.Int).Value = original_EmployeeID;
            cmd.Parameters.Add("@original_FirstName",
                SqlDbType.VarChar, 10).Value = original_FirstName;
            cmd.Parameters.Add("@original_LastName",
                SqlDbType.VarChar, 20).Value = original_LastName;
            cmd.Parameters.Add("@original_Address",
                SqlDbType.VarChar, 60).Value = original_Address;
            cmd.Parameters.Add("@original_City",
                SqlDbType.VarChar, 15).Value = original_City;
            cmd.Parameters.Add("@original_Region",
                SqlDbType.VarChar, 15).Value = original_Region;
            cmd.Parameters.Add("@original_PostalCode",
                SqlDbType.VarChar, 10).Value = original_PostalCode;
    
            int result = 0;
    
            try {
                conn.Open();
                result = cmd.ExecuteNonQuery();
            } catch (SqlException e) {
                // Handle exception.
            } finally {
                conn.Close();
            }
            return result;
        }
    }
    
  7. Do zobrazení Source objektu object.aspx přidejte následující kód:

    <%@ Page language="C#" %>
    <script RunAt="server">
    void EmployeesDetailsView_ItemInserted(Object sender, DetailsViewInsertedEventArgs e) {
        EmployeesGridView.DataBind();
    }
    
    void EmployeesDetailsView_ItemUpdated(Object sender, DetailsViewUpdatedEventArgs e) {
        EmployeesGridView.DataBind();
    }
    
    void EmployeesDetailsView_ItemDeleted(Object sender, DetailsViewDeletedEventArgs e) {
        EmployeesGridView.DataBind();
    }
    void EmployeesGridView_OnSelectedIndexChanged(object sender, EventArgs e) {
        EmployeeDetailsObjectDataSource.SelectParameters["EmployeeID"].DefaultValue =
            EmployeesGridView.SelectedDataKey.Value.ToString();
        EmployeesDetailsView.DataBind();
    }
    void EmployeeDetailsObjectDataSource_OnInserted(object sender,
        ObjectDataSourceStatusEventArgs e) {
    
        EmployeeDetailsObjectDataSource.SelectParameters["EmployeeID"].DefaultValue =
            e.ReturnValue.ToString();
        EmployeesDetailsView.DataBind();
    }
    void EmployeeDetailsObjectDataSource_OnUpdated(object sender,
        ObjectDataSourceStatusEventArgs e) {
    
        if ((int)e.ReturnValue == 0)
            Msg.Text = "Employee was not updated. Please try again.";
    }
    void EmployeeDetailsObjectDataSource_OnDeleted(object sender,
        ObjectDataSourceStatusEventArgs e) {
    
        if ((int)e.ReturnValue == 0)
            Msg.Text = "Employee was not deleted. Please try again.";
    }
    void Page_Load() {
        Msg.Text = "";
    }
    </script>
    <html>
      <body>
        <form id="Form1" runat="server">
          <h3>ObjectDataSource Example</h3>
          <asp:Label id="Msg" runat="server" ForeColor="Red" />
          <asp:ObjectDataSource
              ID="EmployeesObjectDataSource"
              runat="server"
              TypeName="NorthwindData"
              SortParameterName="SortColumns"
              EnablePaging="true"
              SelectCountMethod="SelectCount"
              StartRowIndexParameterName="StartRecord"
              MaximumRowsParameterName="MaxRecords"
              SelectMethod="GetAllEmployees" >
          </asp:ObjectDataSource>
          <asp:ObjectDataSource
              ID="EmployeeDetailsObjectDataSource"
              runat="server"
              TypeName="NorthwindData"
              ConflictDetection="CompareAllValues"
              OldValuesParameterFormatString="{0}"
              SelectMethod="GetEmployee"
              InsertMethod="InsertEmployee"
              UpdateMethod="UpdateEmployee"
              DeleteMethod="DeleteEmployee"
              OnInserted="EmployeeDetailsObjectDataSource_OnInserted"
              OnUpdated="EmployeeDetailsObjectDataSource_OnUpdated"
              OnDeleted="EmployeeDetailsObjectDataSource_OnDeleted">
              <SelectParameters>
                  <asp:Parameter Name="EmployeeID" Type="Int32" />
              </SelectParameters>
          </asp:ObjectDataSource>
          <table cellspacing="10">
            <tr>
              <td valign="top">
                <asp:GridView ID="EmployeesGridView"
                    DataSourceID="EmployeesObjectDataSource"
                    AutoGenerateColumns="false"
                    AllowSorting="true"
                    AllowPaging="true"
                    PageSize="5"
                    DataKeyNames="EmployeeID"
                    OnSelectedIndexChanged="EmployeesGridView_OnSelectedIndexChanged"
                    RunAt="server">
                    <HeaderStyle backcolor="lightblue" forecolor="black"/>
                    <Columns>
                    <asp:ButtonField Text="Details..."
                    HeaderText="Show Details"
                    CommandName="Select"/>
    
                    <asp:BoundField DataField="EmployeeID" HeaderText="Employee ID"
                    SortExpression="EmployeeID" />
                    <asp:BoundField DataField="FirstName" HeaderText="First Name"
                    SortExpression="FirstName" />
                    <asp:BoundField DataField="LastName" HeaderText="Last Name"
                    SortExpression="LastName, FirstName" />
                    </Columns>
                </asp:GridView>
              </td>
              <td valign="top">
                <asp:DetailsView ID="EmployeesDetailsView"
                    DataSourceID="EmployeeDetailsObjectDataSource"
                    AutoGenerateRows="false"
                    EmptyDataText="No records."
                    DataKeyNames="EmployeeID"
                    Gridlines="Both"
                    AutoGenerateInsertButton="true"
                    AutoGenerateEditButton="true"
                    AutoGenerateDeleteButton="true"
                    OnItemInserted="EmployeesDetailsView_ItemInserted"
                    OnItemUpdated="EmployeesDetailsView_ItemUpdated"
                    OnItemDeleted="EmployeesDetailsView_ItemDeleted"
                    RunAt="server">
                    <HeaderStyle backcolor="Navy" forecolor="White"/>
                    <RowStyle backcolor="White"/>
                    <AlternatingRowStyle backcolor="LightGray"/>
                    <EditRowStyle backcolor="LightCyan"/>
                    <Fields>
                        <asp:BoundField DataField="EmployeeID" HeaderText="Employee ID"
                            InsertVisible="False" ReadOnly="true"/>
                        <asp:BoundField DataField="FirstName" HeaderText="First Name"/>
                        <asp:BoundField DataField="LastName" HeaderText="Last Name"/>
                        <asp:BoundField DataField="Address" HeaderText="Address"/>
                        <asp:BoundField DataField="City" HeaderText="City"/>
                        <asp:BoundField DataField="Region" HeaderText="Region"/>
                        <asp:BoundField DataField="PostalCode" HeaderText="Postal Code"/>
                    </Fields>
                  </asp:DetailsView>
                </td>
              </tr>
            </table>
          </form>
        </body>
      </html>
    
  8. Uložte všechny soubory a najděte soubor object.aspx.

  9. Pracujte s rozhraním zobrazením podrobností, úpravou zaměstnanců, přidáváním zaměstnanců a odstraňováním zaměstnanců.