Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
door Scott Mitchell
De TableAdapters in een getypte gegevensset zorgen automatisch voor het maken van verbinding met de database, het uitgeven van opdrachten en het invullen van een DataTable met de resultaten. Er zijn echter situaties waarin we deze details zelf willen uitvoeren. In deze zelfstudie leert u echter hoe u toegang krijgt tot de instellingen op databaseverbindings- en opdrachtniveau in de TableAdapter.
Introductie
In de reeks zelfstudies hebben we Getypte gegevenssets gebruikt om de Data Access-laag en zakelijke objecten van onze gelaagde architectuur te implementeren. Zoals besproken in de eerste zelfstudie, fungeren de DataTables van getypte DataSets als opslagplaatsen van gegevens, waarbij de TableAdapters dienen als wrappers om te communiceren met de database om de onderliggende gegevens op te halen en te wijzigen. De TableAdapters nemen de complexiteit van het werken met de database voor hun rekening en zorgen ervoor dat we geen code hoeven te schrijven om verbinding te maken met de database, een opdracht uit te voeren of de resultaten in een DataTable te vullen.
Er zijn echter momenten waarop we in de diepten van de TableAdapter moeten graven en code moeten schrijven die rechtstreeks met de ADO.NET objecten werkt. In de zelfstudie Databasewijzigingen Inpakken binnen een Transactie hebben we bijvoorbeeld methoden aan de TableAdapter toegevoegd voor het starten, doorvoeren en terugdraaien van ADO.NET-transacties. Deze methoden gebruikten een intern, handmatig gemaakt SqlTransaction object dat is toegewezen aan de TableAdapter-objecten SqlCommand .
In deze zelfstudie bekijken we hoe u toegang krijgt tot de instellingen voor de databaseverbinding en opdrachtniveau in de TableAdapter. In het bijzonder voegen we functionaliteit toe aan de ProductsTableAdapter waarmee toegang tot de onderliggende verbindingsreeks en time-outinstellingen voor commando's mogelijk is.
Werken met gegevens met behulp van ADO.NET
Microsoft .NET Framework bevat een overvloed aan klassen die speciaal zijn ontworpen om met gegevens te werken. Deze klassen, gevonden in de System.Data naamruimte, worden de ADO.NET klassen genoemd. Sommige klassen onder de paraplu ADO.NET zijn gekoppeld aan een bepaalde gegevensprovider. U kunt een gegevensprovider beschouwen als een communicatiekanaal waarmee informatie tussen de ADO.NET klassen en het onderliggende gegevensarchief kan stromen. Er zijn gegeneraliseerde providers, zoals OleDb en ODBC, evenals providers die speciaal zijn ontworpen voor een bepaald databasesysteem. Hoewel het bijvoorbeeld mogelijk is om verbinding te maken met een Microsoft SQL Server-database met behulp van de OleDb-provider, is de SqlClient-provider veel efficiënter omdat deze speciaal is ontworpen en geoptimaliseerd voor SQL Server.
Bij programmatisch toegang tot gegevens wordt het volgende patroon vaak gebruikt:
- Maak een verbinding met de database.
- Geef een opdracht.
- Werk met de resulterende records voor
SELECTqueries.
Er zijn afzonderlijke ADO.NET klassen voor het uitvoeren van elk van deze stappen. Als u verbinding wilt maken met een database met behulp van de SqlClient-provider, gebruikt u bijvoorbeeld de SqlConnection klasse. Als u een INSERT, UPDATEDELETEof SELECT opdracht aan de database wilt uitgeven, gebruikt u de SqlCommand klasse.
Behalve de tutorial Wrapping Database Modifications binnen een Transactie, hebben we geen ADO.NET-code op laag niveau hoeven te schrijven, omdat de automatisch gegenereerde code van TableAdapters de functionaliteit bevat die nodig is om verbinding te maken met de database, opdrachten uit te voeren, gegevens op te halen, en die gegevens in DataTables te vullen. Het kan echter voorkomen dat we deze instellingen op laag niveau moeten aanpassen. In de volgende stappen bekijken we hoe we de ADO.NET objecten die intern door de TableAdapters worden gebruikt, kunt gebruiken.
Stap 1: Onderzoeken met de eigenschap Verbinding
Elke TableAdapter-klasse heeft een Connection eigenschap waarmee de verbindingsgegevens van de database worden opgegeven. Het gegevenstype en de ConnectionString waarde van deze eigenschap worden bepaald door de selecties die zijn gemaakt in de wizard TableAdapter-configuratie. Zoals u zich herinnert, vraagt deze wizard ons om de databasebron (zie afbeelding 1) wanneer we voor het eerst een TableAdapter toevoegen aan een getypte gegevensset. De vervolgkeuzelijst in deze eerste stap bevat de databases die zijn opgegeven in het configuratiebestand, evenals andere databases in de gegevensverbindingen van Server Explorer. Als de database die we willen gebruiken niet bestaat in de vervolgkeuzelijst, kan een nieuwe databaseverbinding worden opgegeven door op de knop Nieuwe verbinding te klikken en de benodigde verbindingsgegevens op te geven.
Afbeelding 1: De eerste stap van de wizard TableAdapter-configuratie (klik om de volledige afbeelding weer te geven)
Laten we even de code voor de eigenschap van de TableAdapter Connection inspecteren. Zoals vermeld in de zelfstudie Een Gegevenstoegangslaag maken , kunnen we de automatisch gegenereerde TableAdapter-code bekijken door naar het venster Class View te gaan, in te zoomen op de juiste klasse en vervolgens te dubbelklikken op de naam van het lid.
Navigeer naar het venster Klasweergave door naar het menu Beeld te gaan en Klasseweergave te kiezen (of door Ctrl+Shift+C te typen). In de bovenste helft van het venster Class View kunt u inzoomen op de NorthwindTableAdapters naamruimte en de ProductsTableAdapter klasse selecteren. Hiermee worden de ProductsTableAdapter leden weergegeven in de onderste helft van de klasseweergave, zoals weergegeven in afbeelding 2. Dubbelklik op de Connection-eigenschap om de code ervan te bekijken.
Afbeelding 2: Double-Click de verbindingseigenschap in de klasseweergave om de automatisch gegenereerde code weer te geven
De eigenschap TableAdapter Connection en andere verbindingsgerelateerde code volgt:
Private _connection As System.Data.SqlClient.SqlConnection
Private Sub InitConnection()
Me._connection = New System.Data.SqlClient.SqlConnection
Me._connection.ConnectionString = _
ConfigurationManager.ConnectionStrings("NORTHWNDConnectionString").ConnectionString
End Sub
Friend Property Connection() As System.Data.SqlClient.SqlConnection
Get
If (Me._connection Is Nothing) Then
Me.InitConnection
End If
Return Me._connection
End Get
Set
Me._connection = value
If (Not (Me.Adapter.InsertCommand) Is Nothing) Then
Me.Adapter.InsertCommand.Connection = value
End If
If (Not (Me.Adapter.DeleteCommand) Is Nothing) Then
Me.Adapter.DeleteCommand.Connection = value
End If
If (Not (Me.Adapter.UpdateCommand) Is Nothing) Then
Me.Adapter.UpdateCommand.Connection = value
End If
Dim i As Integer = 0
Do While (i < Me.CommandCollection.Length)
If (Not (Me.CommandCollection(i)) Is Nothing) Then
CType(Me.CommandCollection(i), _
System.Data.SqlClient.SqlCommand).Connection = value
End If
i = (i + 1)
Loop
End Set
End Property
Wanneer de TableAdapter-klasse wordt geïnstantieerd, is de lidvariabele _connection gelijk aan Nothing. Wanneer de Connection eigenschap wordt geopend, wordt eerst gecontroleerd of de _connection lidvariabele is geïnstantieerd. Als dat niet het geval is, wordt de InitConnection-methode aangeroepen, die _connection instantieert en de ConnectionString-eigenschap instelt op de verbindingsreekswaarde die in de eerste stap van de TableAdapter-configuratiewizard is opgegeven.
De Connection eigenschap kan ook worden toegewezen aan een SqlConnection object. Hiermee koppelt u het nieuwe SqlConnection object aan elk van de TableAdapter-objecten SqlCommand .
Stap 2: Connection-Level-instellingen beschikbaar maken
De verbindingsgegevens moeten worden ingekapseld in de TableAdapter en zijn niet toegankelijk voor andere lagen in de toepassingsarchitectuur. Er kunnen echter scenario's zijn waarin de informatie op verbindingsniveau van TableAdapter toegankelijk of aanpasbaar moet zijn voor een query, gebruiker of ASP.NET pagina.
Laten we de ProductsTableAdapter gegevensset Northwind uitbreiden om een ConnectionString eigenschap op te nemen die door de bedrijfslogicalaag kan worden gebruikt om de verbindingsreeks te lezen of te wijzigen die door de TableAdapter wordt gebruikt.
Opmerking
Een verbindingsreeks is een tekenreeks die databaseverbindingsgegevens opgeeft, zoals de provider die moet worden gebruikt, de locatie van de database, verificatiereferenties en andere database-gerelateerde instellingen. Zie ConnectionStrings.com voor een lijst met verbindingsreekspatronen die worden gebruikt door verschillende gegevensarchieven en providers.
Zoals besproken in de zelfstudie Een Gegevenstoegangslaag maken , kunnen de automatisch gegenereerde klassen van de Getypte Gegevensset worden uitgebreid door het gebruik van gedeeltelijke klassen. Maak eerst een nieuwe submap in het project met de naam ConnectionAndCommandSettings onder de ~/App_Code/DAL map.
Afbeelding 3: Een submap met de naam toevoegen ConnectionAndCommandSettings
Voeg een nieuw klassebestand toe met de naam ProductsTableAdapter.ConnectionAndCommandSettings.vb en voer de volgende code in:
Namespace NorthwindTableAdapters
Partial Public Class ProductsTableAdapter
Public Property ConnectionString() As String
Get
Return Me.Connection.ConnectionString
End Get
Set(ByVal value As String)
Me.Connection.ConnectionString = value
End Set
End Property
End Class
End Namespace
Deze gedeeltelijke klasse voegt een Public eigenschap met de naam ConnectionString toe aan de ProductsTableAdapter klasse waarmee elke laag de verbindingsreeks voor de onderliggende verbinding van TableAdapter kan lezen of bijwerken.
Als deze gedeeltelijke klasse is gemaakt (en opgeslagen), opent u de ProductsBLL klasse. Ga naar een van de bestaande methoden, typ Adapter, en druk vervolgens op de punttoets om IntelliSense weer te geven. U ziet nu de nieuwe ConnectionString eigenschap die beschikbaar is in IntelliSense, wat betekent dat u deze waarde programmatisch kunt lezen of aanpassen vanuit de BLL.
Het hele verbindingsobject beschikbaar maken
Deze gedeeltelijke klasse bevat slechts één eigenschap van het onderliggende verbindingsobject: ConnectionString. Als u het hele verbindingsobject beschikbaar wilt maken buiten de grenzen van de TableAdapter, kunt u ook het beveiligingsniveau van de Connection eigenschap wijzigen. De automatisch gegenereerde code die we in stap 1 hebben onderzocht, heeft aangetoond dat de eigenschap TableAdapter Connection is gemarkeerd als Friend, wat betekent dat deze alleen toegankelijk is voor klassen in dezelfde assembly. Dit kan echter worden gewijzigd via de eigenschap TableAdapter ConnectionModifier .
Open de Northwind DataSet, klik op de ProductsTableAdapter ontwerpfunctie en navigeer naar het venster Eigenschappen. Daar ziet u dat de waarde is ingesteld op de ConnectionModifier standaardwaarde. Assembly Als u de Connection eigenschap beschikbaar wilt maken buiten de getypeerde dataset-assembly, wijzigt u de ConnectionModifier eigenschap in Public.
Afbeelding 4: Het Connection toegankelijkheidsniveau van de eigenschap kan worden geconfigureerd via de ConnectionModifier eigenschap (klik om de afbeelding op volledige grootte weer te geven)
Sla de DataSet op en ga vervolgens terug naar de ProductsBLL klasse. Net als voorheen gaat u naar een van de bestaande methoden en typt u Adapter gevolgd door de punttoets om IntelliSense te openen. De lijst moet een Connection eigenschap bevatten, wat betekent dat u nu programmatisch instellingen op verbindingsniveau van de BLL kunt lezen of toewijzen.
Stap 3: de eigenschappen van de Command-Related bekijken
Een TableAdapter bestaat uit een hoofdquery die standaard automatisch gegenereerde INSERT, UPDATEen DELETE instructies heeft. Deze hoofdquery's INSERT, UPDATE, en DELETE-instructies worden geïmplementeerd in de TableAdapter-code als een ADO.NET-gegevensadapterobject via de Adapter eigenschap. Net als bij Connection de eigenschap wordt het gegevenstype van de Adapter eigenschap bepaald door de gegevensprovider die wordt gebruikt. Omdat deze zelfstudies de SqlClient-provider gebruiken, is de eigenschap van het Adapter type SqlDataAdapter.
De TableAdapter eigenschap Adapter heeft drie eigenschappen van het type SqlCommand die worden gebruikt om de INSERT, UPDATE, en DELETE instructies uit te geven:
InsertCommandUpdateCommandDeleteCommand
Een SqlCommand object is verantwoordelijk voor het verzenden van een bepaalde query naar de database en heeft eigenschappen als: CommandText, die de ad-hoc SQL-instructie of opgeslagen procedure bevat die moet worden uitgevoerd; en Parameters, een verzameling van SqlParameter objecten. Zoals we hebben gezien in de zelfstudie Een Gegevenstoegangslaag maken , kunnen deze opdrachtobjecten worden aangepast via het venster Eigenschappen.
Naast de hoofdquery kan de TableAdapter een variabel aantal methoden bevatten die, wanneer deze worden aangeroepen, een opgegeven opdracht naar de database verzenden. Het opdrachtobject van de hoofdquery en de opdrachtobjecten voor alle aanvullende methoden worden opgeslagen in de eigenschap TableAdapter CommandCollection .
Laten we even kijken naar de code die is gegenereerd door ProductsTableAdapter in de Northwind DataSet voor deze twee eigenschappen en hun ondersteunende lidvariabelen en helpermethoden.
Private WithEvents _adapter As System.Data.SqlClient.SqlDataAdapter
Private Sub InitAdapter()
Me._adapter = New System.Data.SqlClient.SqlDataAdapter
... Code that creates the InsertCommand, UpdateCommand, ...
... and DeleteCommand instances - omitted for brevity ...
End Sub
Private ReadOnly Property Adapter() As System.Data.SqlClient.SqlDataAdapter
Get
If (Me._adapter Is Nothing) Then
Me.InitAdapter
End If
Return Me._adapter
End Get
End Property
Private _commandCollection() As System.Data.SqlClient.SqlCommand
Private Sub InitCommandCollection()
Me._commandCollection = New System.Data.SqlClient.SqlCommand(8) {}
... Code that creates the command objects for the main query and the ...
... ProductsTableAdapter�s other eight methods - omitted for brevity ...
End Sub
Protected ReadOnly Property CommandCollection() As System.Data.SqlClient.SqlCommand()
Get
If (Me._commandCollection Is Nothing) Then
Me.InitCommandCollection
End If
Return Me._commandCollection
End Get
End Property
De code voor de Adapter en CommandCollection eigenschappen bootst die van de Connection eigenschap nauw na. Er zijn lidvariabelen die de objecten bevatten die door de eigenschappen worden gebruikt. De eigenschapstoegangsmethoden Get beginnen met controleren of de bijbehorende lidvariabele Nothing is. Als dit het geval is, wordt een initialisatiemethode aangeroepen waarmee een exemplaar van de lidvariabele wordt gemaakt en de belangrijkste eigenschappen van de opdracht worden toegewezen.
Stap 4: Command-Level-instellingen beschikbaar maken
In het ideale geval moet de informatie op opdrachtniveau ingekapseld blijven binnen de Gegevenstoegangslaag. Als deze informatie nodig is in andere lagen van de architectuur, kan deze echter worden weergegeven via een gedeeltelijke klasse, net als bij de instellingen op verbindingsniveau.
Omdat TableAdapter slechts één Connection eigenschap heeft, is de code voor het weergeven van instellingen op verbindingsniveau vrij eenvoudig. Dingen zijn iets ingewikkelder bij het wijzigen van instellingen op opdrachtniveau, omdat de TableAdapter meerdere opdrachtobjecten kan hebben: een InsertCommand, UpdateCommanden, samen DeleteCommandmet een variabel aantal opdrachtobjecten in de CommandCollection eigenschap. Wanneer u instellingen op opdrachtniveau bijwerkt, moeten deze instellingen worden doorgegeven aan alle opdrachtobjecten.
Stel dat er bepaalde query's in de TableAdapter zijn die een buitengewone lange tijd hebben geduurd om uit te voeren. Wanneer u de TableAdapter gebruikt om een van deze query's uit te voeren, is het misschien handig om de eigenschap van CommandTimeouthet opdrachtobject te verhogen. Met deze eigenschap geeft u het aantal seconden op dat moet worden gewacht totdat de opdracht wordt uitgevoerd en de standaardwaarde is ingesteld op 30.
Als u wilt toestaan dat de CommandTimeout eigenschap wordt aangepast door de BLL, voegt u de volgende Public methode toe aan de ProductsDataTable met behulp van het gedeeltelijke class bestand dat is gemaakt in stap 2 (ProductsTableAdapter.ConnectionAndCommandSettings.vb).
Public Sub SetCommandTimeout(ByVal timeout As Integer)
If Me.Adapter.InsertCommand IsNot Nothing Then
Me.Adapter.InsertCommand.CommandTimeout = timeout
End If
If Me.Adapter.DeleteCommand IsNot Nothing Then
Me.Adapter.DeleteCommand.CommandTimeout = timeout
End If
If Me.Adapter.UpdateCommand IsNot Nothing Then
Me.Adapter.UpdateCommand.CommandTimeout = timeout
End If
For i As Integer = 0 To Me.CommandCollection.Length - 1
If Me.CommandCollection(i) IsNot Nothing Then
Me.CommandCollection(i).CommandTimeout = timeout
End If
Next
End Sub
Deze methode kan worden aangeroepen vanuit de BLL-laag of de Presentatielaag om de time-out van de opdracht in te stellen voor alle opdrachten uitgegeven door dat TableAdapter-exemplaar.
Opmerking
De Adapter eigenschappen CommandCollection worden gemarkeerd als Private, wat betekent dat ze alleen kunnen worden geopend vanuit code binnen de TableAdapter. In tegenstelling tot de Connection eigenschap kunnen deze toegangsaanpassingen niet worden geconfigureerd. Als u daarom eigenschappen op opdrachtniveau beschikbaar wilt maken voor andere lagen in de architectuur, moet u de hierboven besproken gedeeltelijke klassebenadering gebruiken om een Public methode of eigenschap op te geven die naar de Private opdrachtobjecten leest of schrijft.
Samenvatting
De TableAdapters in een getypte gegevensset dienen om details en complexiteit van gegevensopvraging te encapsuleren. Met TableAdapters hoeft u zich geen zorgen te maken over het schrijven van ADO.NET code om verbinding te maken met de database, een opdracht uit te geven of de resultaten in een gegevenstabel te vullen. Het wordt allemaal automatisch voor ons afgehandeld.
Het kan echter voorkomen dat we de specifieke ADO.NET op laag niveau moeten aanpassen, zoals het wijzigen van de verbindingsreeks of de standaardwaarden voor de verbinding of de time-outwaarden van de opdracht. De TableAdapter heeft de eigenschappen Connection, Adapter en CommandCollection automatisch gegenereerd, maar deze zijn standaard Friend of Private. Deze interne informatie kan worden weergegeven door de TableAdapter uit te breiden met behulp van gedeeltelijke klassen om methoden of eigenschappen op te nemen Public . U kunt ook de eigenschapstoegangsmodificator van de TableAdapter Connection configureren door middel van de eigenschap TableAdapter ConnectionModifier.
Veel plezier met programmeren!
Over de auteur
Scott Mitchell, auteur van zeven ASP/ASP.NET-boeken en oprichter van 4GuysFromRolla.com, werkt sinds 1998 met Microsoft-webtechnologieën. Scott werkt als onafhankelijk consultant, trainer en schrijver. Zijn laatste boek is Sams Teach Yourself ASP.NET 2.0 in 24 uur. Hij kan worden bereikt op mitchell@4GuysFromRolla.com.
Speciale dank aan
Deze tutorialreeks is beoordeeld door veel behulpzame beoordelers. Hoofdrevisoren voor deze zelfstudie waren Burnadette Leigh, S ren Jacob Lauritsen, Teresa Murphy en Hilton Geisenow. Bent u geïnteresseerd in het bekijken van mijn aanstaande MSDN-artikelen? Zo ja, laat iets van je horen via mitchell@4GuysFromRolla.com.