Sdílet prostřednictvím


Konfigurace nastavení datové přístupové vrstvy, a to jak na úrovni připojení, tak na úrovni příkazů (C#)

od Scotta Mitchella

Stáhnout PDF

Objekty TableAdapter v typizované datové sadě se automaticky postarají o připojení k databázi, vydávání příkazů a naplnění DataTable výsledky. Existují však situace, kdy se chceme o tyto podrobnosti postarat sami, a v tomto kurzu se dozvíme, jak přistupovat k nastavení připojení k databázi a nastavení na úrovni příkazů v TableAdapter.

Úvod

V celé sérii kurzů jsme použili typové datové sady k implementaci vrstvy přístupu k datům a obchodních objektů naší vrstvené architektury. Jak je popsáno v prvním kurzu, datové tabulky Typed DataSet s slouží jako úložiště dat, zatímco Objekty TableAdapter fungují jako obálky pro komunikaci s databází za účelem načtení a úpravy podkladových dat. Objekty TableAdapter zapouzdřují složitost při práci s databází a šetří nás od nutnosti psát kód pro připojení k databázi, vydat příkaz nebo naplnit výsledky do tabulky DataTable.

Existují však časy, kdy potřebujeme vnořit do hloubky TableAdapter a napsat kód, který funguje přímo s ADO.NET objekty. V tutoriálu Obalení změn databáze v rámci transakcí jsme například přidali metody do TableAdapteru pro zahájení, potvrzení a zrušení ADO.NET transakcí. Tyto metody používaly interní ručně vytvořený SqlTransaction objekt, který byl přiřazen objektům TableAdapter s SqlCommand .

V tomto kurzu se podíváme, jak získat přístup k nastavení připojení k databázi a nastavení na úrovni příkazů v tabulce TableAdapter. Konkrétně přidáme funkce, ProductsTableAdapter které umožňují přístup k základnímu připojovacímu řetězci a nastavení časového limitu příkazů.

Práce s daty pomocí ADO.NET

Rozhraní Microsoft .NET Framework obsahuje řadu tříd navržených speciálně pro práci s daty. Tyto třídy, nalezené v System.Data oboru názvů, jsou označovány jako ADO.NET třídy. Některé třídy pod ADO.NET deštníkem jsou svázané s konkrétním poskytovatelem dat. Poskytovatele dat si můžete představit jako komunikační kanál, který umožňuje tok informací mezi třídami ADO.NET a podkladovým úložištěm dat. Existují zobecnění poskytovatelé, jako je OleDb a ODBC, a také poskytovatelé, kteří jsou speciálně navrženi pro konkrétní databázový systém. Pokud je například možné se připojit k databázi Microsoft SQL Serveru pomocí zprostředkovatele OleDb, poskytovatel SqlClient je mnohem efektivnější, protože byl navržen a optimalizován speciálně pro SQL Server.

Při programovém přístupu k datům se běžně používá následující vzor:

  • Vytvořte připojení k databázi.
  • Zadejte příkaz.
  • U SELECT dotazů můžete pracovat s výslednými záznamy.

Pro provedení každého z těchto kroků existují samostatné třídy ADO.NET. Pokud se chcete připojit k databázi pomocí zprostředkovatele SqlClient, například použijte SqlConnection třídu. K vydání příkazu INSERT, , UPDATEDELETEnebo SELECT do databáze, použijte SqlCommand třídu.

Kromě kurzu Uložit úpravy databáze v rámci transakce jsme nemuseli sami psát žádný nízkoúrovňový kód ADO.NET, protože automaticky generovaný kód TableAdapter zahrnuje funkce potřebné pro připojení k databázi, vydávání příkazů, načítání dat a naplňuje tato data do objektů DataTable. Někdy ale může docházet k tomu, že potřebujeme tato nastavení nízké úrovně přizpůsobit. V následujících několika krocích prozkoumáme, jak se napojit na objekty ADO.NET používané vnitřně TableAdaptery.

Krok 1: Zkoumání vlastnosti připojení

Každá třída TableAdapter má Connection vlastnost, která určuje informace o připojení databáze. Tento datový typ a ConnectionString hodnota této vlastnosti jsou určeny výběrem v Průvodci konfigurací objektu TableAdapter. Vzpomeňte si, že při prvním přidání objektu TableAdapter do typové datové sady nás tento průvodce požádá o zdroj databáze (viz obrázek 1). Rozevírací seznam v tomto prvním kroku zahrnuje tyto databáze zadané v konfiguračním souboru i všechny ostatní databáze v datových připojeních Průzkumníka serveru. Pokud databáze, kterou chceme použít, v rozevíracím seznamu neexistuje, můžete zadat nové připojení k databázi kliknutím na tlačítko Nové připojení a zadáním potřebných informací o připojení.

První krok Průvodce konfigurací TableAdapter

Obrázek 1: První krok Průvodce konfigurací TableAdapter (kliknutím zobrazíte obrázek v plné velikosti)

Pojďme chvíli zkontrolovat kód pro vlastnost TableAdapter s Connection . Jak je uvedeno v kurzu Vytvoření vrstvy přístupu k datům , můžeme zobrazit automaticky vygenerovaný kód TableAdapter tak, že přejdete do okna Zobrazení třídy, přejdeme k podrobnostem příslušné třídy a potom poklikneme na název člena.

Přejděte do okna Zobrazení třídy tím, že v nabídce Zobrazení zvolíte Zobrazení třídy (nebo zadáte Ctrl+Shift+C). V horní polovině okna Zobrazení třídy rozbalte obor názvů NorthwindTableAdapters a vyberte třídu ProductsTableAdapter. Se zobrazí členové ProductsTableAdapter v dolní polovině zobrazení třídy, jak je znázorněno na obrázku 2. Poklikáním na Connection vlastnost zobrazíte jeho kód.

Double-Click vlastnost připojení v zobrazení třídy k zobrazení jeho automaticky generovaného kódu

Obrázek 2: Double-Click vlastnost připojení ve zobrazení třídy pro zobrazení jeho automaticky generovaného kódu

Vlastnost TableAdapter s Connection a další kód související s připojením:

private System.Data.SqlClient.SqlConnection _connection;
private void InitConnection() {
    this._connection = new System.Data.SqlClient.SqlConnection();
    this._connection.ConnectionString = 
        ConfigurationManager.ConnectionStrings["NORTHWNDConnectionString"].ConnectionString;
}
internal System.Data.SqlClient.SqlConnection Connection {
    get {
        if ((this._connection == null)) {
            this.InitConnection();
        }
        return this._connection;
    }
    set {
        this._connection = value;
        if ((this.Adapter.InsertCommand != null)) {
            this.Adapter.InsertCommand.Connection = value;
        }
        if ((this.Adapter.DeleteCommand != null)) {
            this.Adapter.DeleteCommand.Connection = value;
        }
        if ((this.Adapter.UpdateCommand != null)) {
            this.Adapter.UpdateCommand.Connection = value;
        }
        for (int i = 0; (i < this.CommandCollection.Length); i = (i + 1)) {
            if ((this.CommandCollection[i] != null)) {
                ((System.Data.SqlClient.SqlCommand)
                    (this.CommandCollection[i])).Connection = value;
            }
        }
    }
}

Při vytvoření instance třídy TableAdapter je členská proměnná _connection rovna null. Při přístupu k Connection vlastnosti se nejprve zkontroluje, zda byla inicializována členská proměnná _connection. Pokud tomu tak není, je vyvolána metoda InitConnection, která vytvoří instanci _connection a nastaví její ConnectionString vlastnost na hodnotu připojovacího řetězce zadanou v prvním kroku průvodce TableAdapter Configuration.

Vlastnost Connection lze také přiřadit k objektu SqlConnection . Tímto způsobem přidružíte nový SqlConnection objekt ke každému z objektů TableAdapteru SqlCommand.

Krok 2: Zveřejnění nastavení Connection-Level

Informace o připojení by měly zůstat zapouzdřené v objektu TableAdapter a neměly by být přístupné jiným vrstvám v architektuře aplikace. Mohou však existovat scénáře, kdy musí být informace na úrovni připojení TableAdapter přístupné nebo přizpůsobitelné pro dotaz, uživatele nebo ASP.NET stránku.

Pojďme rozšířit ProductsTableAdapter datovou Northwind sadu tak, aby zahrnovala ConnectionString vlastnost, kterou může vrstva obchodní logiky použít ke čtení nebo změně připojovacího řetězce používaného objektem TableAdapter.

Poznámka:

Připojovací řetězec je řetězec, který určuje informace o připojení k databázi, jako je poskytovatel, který se má použít, umístění databáze, přihlašovací údaje pro ověření a další nastavení související s databází. Seznam vzorů připojovacích řetězců používaných různými úložišti dat a poskytovateli najdete na ConnectionStrings.com.

Jak je popsáno v kurzu Vytvoření vrstvy přístupu k datům, auto-generované třídy typové datové sady lze rozšířit pomocí částečných tříd. Nejprve vytvořte novou podsložku v projektu s názvem ConnectionAndCommandSettings pod složkou ~/App_Code/DAL .

Přidání podsložky s názvem ConnectionAndCommandSettings

Obrázek 3: Přidání podsložky s názvem ConnectionAndCommandSettings

Přidejte nový soubor třídy s názvem ProductsTableAdapter.ConnectionAndCommandSettings.cs a zadejte 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;
namespace NorthwindTableAdapters
{
    public partial class ProductsTableAdapter
    {
        public string ConnectionString
        {
            get
            {
                return this.Connection.ConnectionString;
            }
            set
            {
                this.Connection.ConnectionString = value;
            }
        }
    }
}

Tato částečná třída přidá vlastnost pojmenovanou publicConnectionString do ProductsTableAdapter třídy, která umožňuje jakékoli vrstvě číst nebo aktualizovat připojovací řetězec pro základní připojení TableAdapter.

Po vytvoření (a uložení) této částečné třídy otevřete třídu ProductsBLL. Přejděte k některé z existujících metod a zadejte Adapter, a poté stiskněte klávesu tečky, aby se otevřelo IntelliSense. Měla by se zobrazit nová ConnectionString vlastnost dostupná v IntelliSense, což znamená, že tuto hodnotu můžete číst nebo upravovat programově z knihovny BLL.

Zveřejnění celého objektu připojení

Tato částečná třída zveřejňuje pouze jednu vlastnost základního objektu připojení: ConnectionString. Pokud chcete zpřístupnit celý objekt připojení nad rámec omezení objektu TableAdapter, můžete případně změnit Connection úroveň ochrany vlastnosti. Automaticky vygenerovaný kód, který jsme prozkoumali v kroku 1, ukázal, že Vlastnost TableAdapter s Connection je označena jako internal, což znamená, že k němu lze přistupovat pouze třídami ve stejném sestavení. To však lze změnit pomocí vlastnosti TableAdapteru ConnectionModifier.

Otevřete sadu dat Northwind, klikněte v Návrháři ProductsTableAdapter a přejděte na okno Vlastnosti. Tam uvidíte ConnectionModifier nastaveno na svou výchozí hodnotu, Assembly. Chcete-li zpřístupnit Connection vlastnost mimo sestavení Typed DataSet, změňte ConnectionModifier vlastnost na Public.

Úroveň přístupnosti vlastnosti připojení lze nakonfigurovat prostřednictvím vlastnosti ConnectionModifier.

Obrázek 4: Connection Úroveň přístupnosti vlastnosti lze konfigurovat prostřednictvím ConnectionModifier vlastnosti (kliknutím zobrazíte obrázek v plné velikosti).

Uložte DataSet a vraťte se do ProductsBLL třídy. Stejně jako předtím přejděte k některé z existujících metod a zadejte Adapter a poté stiskněte klávesu s tečkou pro vyvolání IntelliSense. Seznam by měl obsahovat Connection vlastnost, což znamená, že teď můžete programově číst nebo přiřazovat nastavení na úrovni připojení z BLL.

Objekt TableAdapter se skládá z hlavního dotazu, který má ve výchozím nastavení automaticky vygenerovaný INSERT, UPDATEa DELETE příkazy. Tento hlavní dotaz s příkazy INSERT, UPDATE, a DELETE je implementován v kódu TableAdapteru jako ADO.NET objekt datového adaptéru prostřednictvím vlastnosti Adapter. Stejně jako u vlastnosti ConnectionAdapter se datový typ vlastnosti určuje použitým poskytovatelem dat. Vzhledem k tomu, že tyto kurzy používají zprostředkovatele SqlClient, Adapter vlastnost je typu SqlDataAdapter.

Vlastnost TableAdapter s Adapter má tři vlastnosti typu SqlCommand , které používá k vydání INSERT, UPDATEa DELETE příkazy:

  • InsertCommand
  • UpdateCommand
  • DeleteCommand

Objekt SqlCommand je zodpovědný za odeslání konkrétního dotazu do databáze a má vlastnosti jako: CommandText, který obsahuje příkaz AD hoc SQL nebo uloženou proceduru ke spuštění; a Parameters, což je kolekce SqlParameter objektů. Jak jsme viděli zpět v kurzu Vytvoření vrstvy přístupu k datům , lze tyto příkazové objekty přizpůsobit prostřednictvím okna Vlastnosti.

Kromě hlavního dotazu může TableAdapter obsahovat proměnný počet metod, které při vyvolání odešle zadaný příkaz do databáze. Objekt příkazu hlavního dotazu a objekty příkazů pro všechny další metody jsou uloženy ve vlastnosti TableAdapter s CommandCollection .

Pojďme se chvíli podívat na kód vygenerovaný ProductsTableAdapter v datové Northwind sadě pro tyto dvě vlastnosti a jejich podpůrné členské proměnné a pomocné metody:

private System.Data.SqlClient.SqlDataAdapter _adapter;
private void InitAdapter() {
    this._adapter = new System.Data.SqlClient.SqlDataAdapter();
    
    ... Code that creates the InsertCommand, UpdateCommand, ...
    ... and DeleteCommand instances - omitted for brevity ...
}
private System.Data.SqlClient.SqlDataAdapter Adapter {
    get {
        if ((this._adapter == null)) {
            this.InitAdapter();
        }
        return this._adapter;
    }
}
private System.Data.SqlClient.SqlCommand[] _commandCollection;
private void InitCommandCollection() {
    this._commandCollection = new System.Data.SqlClient.SqlCommand[9];
    ... Code that creates the command objects for the main query and the ...
    ... ProductsTableAdapter�s other eight methods - omitted for brevity ...
}
protected System.Data.SqlClient.SqlCommand[] CommandCollection {
    get {
        if ((this._commandCollection == null)) {
            this.InitCommandCollection();
        }
        return this._commandCollection;
    }
}

Kód pro vlastnosti Adapter a CommandCollection úzce napodobuje kód pro vlastnost Connection. Existují členské proměnné, které obsahují objekty používané vlastnostmi. Přístupové objekty vlastností get začínají kontrolou, zda členská proměnná odpovídající null má hodnotu. Pokud ano, volá se inicializační metoda, která vytvoří instanci členské proměnné a přiřadí základní vlastnosti související s příkazy.

Krok 4: Zveřejnění nastavení Command-Level

V ideálním případě by informace na úrovni příkazů měly zůstat zapouzdřené ve vrstvě přístupu k datům. Pokud by však tyto informace byly potřeba v jiných vrstvách architektury, můžou být zpřístupněny prostřednictvím částečné třídy, stejně jako u nastavení na úrovni připojení.

Protože TableAdapter má pouze jednu Connection vlastnost, kód pro zveřejnění nastavení na úrovni připojení je poměrně jednoduchý. Věci jsou trochu složitější při úpravě nastavení na úrovni příkazů, protože TableAdapter může mít více objektů příkazů - an InsertCommand, UpdateCommanda DeleteCommand, spolu s proměnným počtem objektů příkazů ve CommandCollection vlastnosti. Při aktualizaci nastavení na úrovni příkazů bude nutné tato nastavení rozšířit do všech objektů příkazů.

Představte si například, že v objektu TableAdapter byly určité dotazy, které trvaly mimořádně dlouhou dobu, než se spustily. Při použití Objektu TableAdapter ke spuštění jednoho z těchto dotazů můžeme chtít zvýšit vlastnost objektu CommandTimeoutpříkazu. Tato vlastnost určuje počet sekund čekání na spuštění příkazu a výchozí hodnota 30.

Chcete-li umožnit úpravu vlastnosti CommandTimeout prostřednictvím BLL, přidejte následující public metodu do ProductsDataTable, použijte soubor částečné třídy z kroku 2 (ProductsTableAdapter.ConnectionAndCommandSettings.cs):

public void SetCommandTimeout(int timeout)
{
    if (this.Adapter.InsertCommand != null)
        this.Adapter.InsertCommand.CommandTimeout = timeout;
    if (this.Adapter.DeleteCommand != null)
        this.Adapter.DeleteCommand.CommandTimeout = timeout;
    if (this.Adapter.UpdateCommand != null)
        this.Adapter.UpdateCommand.CommandTimeout = timeout;
    for (int i = 0; i < this.CommandCollection.Length; i++)
        if (this.CommandCollection[i] != null)
            this.CommandCollection[i].CommandTimeout = timeout;
}

Tuto metodu lze vyvolat z BLL nebo prezentační vrstvy k nastavení časového limitu příkazu pro všechny problémy s příkazy v instanci TableAdapter.

Poznámka:

Vlastnosti Adapter a CommandCollection jsou označené jako private, což znamená, že k nim lze přistupovat pouze z kódu v rámci TableAdapteru. Connection Na rozdíl od vlastnosti nejsou tyto modifikátory přístupu konfigurovatelné. Proto, pokud potřebujete zveřejnit vlastnosti na úrovni příkazů pro jiné vrstvy v architektuře, musíte použít výše zmíněný přístup částečné třídy, abyste poskytli metodu public nebo vlastnost, která čte nebo zapisuje do objektů příkazů private.

Shrnutí

TableAdaptery v rámci typové datové sady slouží k zapouzdření podrobností o přístupu k datům a složitosti. Pomocí objektů TableAdapter se nemusíme starat o zápis kódu ADO.NET pro připojení k databázi, vydání příkazu nebo naplnění výsledků do tabulky DataTable. Všechno se pro nás zpracovává automaticky.

Někdy ale může nastat potřeba, abychom přizpůsobili specifika nízké úrovně ADO.NET, například změnili připojovací řetězec nebo výchozí časový limit pro připojení nebo příkaz. Objekt TableAdapter má automaticky vygenerované Connection, Adapter a CommandCollection vlastnosti, ale ve výchozím nastavení jsou buďto internal nebo private. Tyto interní informace lze zpřístupnit rozšířením třídy TableAdapter pomocí částečných tříd, aby zahrnovaly public metody nebo vlastnosti. Alternativně lze modifikátor přístupu k vlastnostem TableAdapter s Connection nakonfigurovat prostřednictvím vlastnosti TableAdapter s ConnectionModifier .

Šť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 Burnadette Leigh, S ren Jacob Lauritsen, Teresa Murphy a Hilton Geisenow. Chcete si projít nadcházející články MSDN? Pokud ano, napište mi zprávu na mitchell@4GuysFromRolla.com.